Introduction

This is a curated dataset containing the Africa, Brazil, India, and the G6 datasets, which are all TB datasets with active TB patients, patients that will progress to active TB, and people with TB infection who don’t progress. There is a batch effect especially with the Brazil data. This object is a SummarizedExperiment with 7 assays. The ‘combat’ assay was made by running the logtpm values through combat with ‘SequencingBatch’ as the batch and ‘Label’ as the covariate. “Label” is the condition Non-progressor, Progressor, and Active.

Overall design

The combined dataset contains 4 studies, in which Brazil dataset has 2 batches within the study:

  • Africa: 197 samples, (104 Non-progressor, 77 Progressor, 16 Active)
  • Brazil: 51 samples, (21 Non-progressor, 16 Progressor, 14 Active)
    • Batch 1: 39 samples, (9 Non-progressor, 16 Progressor, 14 Active)
    • Batch 2: 12 samples, (12 Non-progressor, 0 Progressor, 0 Active)
  • G6: 399 samples, (304 Non-progressor, 95 Progressor, 0 Active)
  • India: 44 samples, (19 Non-progressor, 0 Progressor, 25 Active)

Note: Gender is an important factor in this study.

Load data & summarize basic info

After loading the data, we calculate a few basic statistics of the dataset.

######  Samples  #######
- Total number of samples:
[1] 691

- Number of samples in condition groups:
group
Non-progressor     Progressor         Active 
           448            188             55 

- Number of samples in batches:
batch
  Africa Brazil_1 Brazil_2       G6    India 
     197       39       12      399       44 

In each batch separately:
         Non-progressor Progressor Active
Africa              104         77     16
Brazil_1              9         16     14
Brazil_2             12          0      0
G6                  304         95      0
India                19          0     25


######  Genes  #######
- Total number of genes:
[1] 24391

- Number of genes with 0 counts:
14504 59.5%

- Number of genes with maximum 10 counts:
2587 10.6%

- Number of genes with ONLY 0s:
0 0%


######  Counts  #######
- Range of count in whole dataset:
[1]       0 7674206

- Average count in whole dataset:
[1] "Mean: 2350.9"
[1] "Median: 75"

There are no genes with only zero values across all samples (probably because of cleaning in the curation stage). The figure below shows distribution of percentages of zero counts for the remaining genes (each data point represents a gene, i.e., how many zeros are there in each gene).

######  Proportion of genes with X% zeros across samples  #######
 <10.0%  <20.0%  <30.0%  <40.0%  <50.0%  <60.0%  <70.0%  <80.0%  <90.0% <100.0% 
  0.646   0.033   0.023   0.020   0.020   0.021   0.025   0.029   0.045   0.139 

Existence of batch effect

In this merged dataset, there are both “study effects” across the 4 studies (targeting different populations), and batch effect within the same study (Brazil dataset).

PCA

PCA (Brazil only)

Dendrograms (Brazil only)

Library size

Next, we take a look at the observed library sizes of samples, and to see if there is a difference in library size across batches.

Range of observed library sizes across samples:
[1] "4.91e+05" "1.09e+08"

Gene expression distribution

Our next step is to interrogate the gene expression distributions.

Fold changes in mean

We use edgeR to perform differential expression analysis, and calculate (log-) fold changes of all genes between condition groups and batches.

Change WRT condition

To rule out the impact of batch effect, we limit our DE analysis with regard to biological condition in one of the batches. Here we specify the batch to be G6 due to a larger batch size, and evaluate DE between progressors and non-progressors.

####  Differential genes relative to biological condition 
####  (within batch 1 / batch specified by 'test_batch')
test_batch <- "G6"
counts_batch <- assay(rds_obj,"counts")[, batch==test_batch]
cond_batch <- as.factor(as.character(group[batch==test_batch]))
y <- DGEList(counts=counts_batch, group=as.factor(cond_batch))
y <- calcNormFactors(y, method="TMM")
design <- model.matrix(~as.factor(cond_batch))
y <- estimateDisp(y, design)
######  Changes in terms of average gene counts  ######
               top50 up top50 down 100 least DE
Non-progressor   1728.5     3362.2        757.1
Progressor       3117.4     2773.3        706.5

######  Range of fold change across biological conditions  ######
          top50 up top50 down 100 least DE
min FC       1.501      0.004        0.934
median FC    3.975      0.705        1.000
mean FC     21.299      0.563        0.998
max FC     668.720      0.899        1.000

######  Range of Log(fold change) across biological conditions  ######
             top50 up top50 down 100 least DE
min logFC       0.406     -5.553       -0.068
median logFC    1.380     -0.350        0.000
mean logFC      3.059     -0.574       -0.002
max logFC       6.505     -0.107        0.000

Conclusions:

  • Biological fold change comparing average counts in top DE genes is about 1.2-1.8.
  • Gene-wise fold change in top DE genes has a wide range (median 4, mean 21).

Change WRT batch

We are also interested to see how the average (mean) gene counts change across batches (i.e. degree of mean batch effect).

To explore this mean batch effect, we first perform DE with regard to the batch variable. To rule out the impact of biological condition, we perform this analysis within Non-progressors only, and compare Africa & G6 studies. Note that this DE is not true DE - it’s testing if there is a significant mean difference between two batches.

####  Differential genes relative to batch 
####  (within condition 0 / condition specified by 'test_cond')
rds_subset <- rds_obj[, rds_obj$Dataset %in% c("Africa", "G6")]
test_cond <- "Non-progressor"
counts_cond <- assay(rds_subset, "counts")[, rds_subset$Label==test_cond]
batch_cond <- as.factor(as.character(rds_subset$SequencingBatch[rds_subset$Label==test_cond]))
y <- DGEList(counts=counts_cond, group=as.factor(batch_cond))
y <- calcNormFactors(y, method="TMM")
design <- model.matrix(~as.factor(batch_cond))
y <- estimateDisp(y, design)
fit <- glmQLFit(y, design)
qlf <- glmQLFTest(fit, coef=2)
de_res <- topTags(qlf, n=nrow(rds_subset))
up_genes <- rownames(de_res)[de_res$table$logFC >= 0]  # all up-regulated genes
head_up_genes <- head(up_genes, n=50)  # top-50 up-regulated genes
tail_up_genes <- tail(up_genes, n=50)  # 50 least up-regulated genes
batch_up_inds <- up_genes
down_genes <- rownames(de_res)[de_res$table$logFC < 0]  # all down-regulated genes
head_down_genes <- head(down_genes, n=50)  # top-50 down-regulated genes
tail_down_genes <- tail(down_genes, n=50)  # 50 least down-regulated genes
batch_down_inds <- down_genes
######  Batch differences in terms of mean gene counts  ######
       top50 up top50 down 100 least changed
Africa  1917.33    4100.75             96.39
G6      6824.55    3466.82            142.55

######  Range of fold change between batches  ######
- All genes - FC:
0.005 1291.191

- All genes - log(FC):
-5.352 7.163

- Top genes - FC:
          top50 up top50 down 100 least DE
min FC       1.872      0.005        0.953
median FC    4.424      0.425        1.000
mean FC     52.612      0.410        0.996
max FC    1291.191      0.609        1.000

- Top genes - log(FC):
             top50 up top50 down 100 least DE
min logFC       0.627     -5.352       -0.049
median logFC    1.487     -0.856        0.000
mean logFC      3.963     -0.892       -0.004
max logFC       7.163     -0.496        0.000

Conclusions:

  • Mean batch effect fold change comparing average counts in top genes ranges from 1.18-3.56. Remember that these are genes most significantly different across batch.
  • Gene-wise mean batch effect fold change in top genes has a wide range (mean 4.4, median 52.6).

Batch mean

Median (of all genes) gene-wise mean:

               Africa     G6 Brazil1
Non-progressor  87.85 129.77   15.00
Progressor      74.19 119.88   22.75

Scaled by that of Africa:

               Africa   G6 Brazil1
Non-progressor      1 1.48    0.17
Progressor          1 1.62    0.31

Batch dispersion

Aside from average gene counts, we are interested in comparing dispersions in the batches. Difference in the dispersions across batches suggests variance batch effect not accounted for by Poisson model. We visualize the gene-wise dispersion estimates from edgeR:

Design matrix not provided. Switch to the classic mode.
####  Statistics about dispersion estimates from the two batches  ####
               Africa       G6   India Brazil_1 Brazil_2
min disp.      0.0054   0.0034  0.0001   0.0390   0.0305
median disp.   0.1916   0.2422  0.1616   0.6837   0.2086
mean disp.     3.3203   2.7797  0.3211   3.0653   0.4466
max disp.    102.4000 102.4000 50.4797  38.5716   6.2874

Conclusions:

  • Mean dispersion in the Africa / Batch 1 in the Brazil study is about 10 times of those in the India study.
  • We see huge max gene-wise dispersions, possibly caused by 0 counts.

Batch variance

Median (of all genes) gene-wise variance:

                Africa      G6 Brazil1
Non-progressor 1967.72 4722.60  135.19
Progressor     1620.59 4623.17  469.53

Scaled by that of Africa:

               Africa   G6 Brazil1
Non-progressor      1 2.40    0.07
Progressor          1 2.85    0.29

Impact of 0 counts on gene distributions

We have seen above that over half of genes in the dataset contain some portions of zeros. Having 0 counts can have a good impact on mean and dispersion estimation. We evaluate such impact in this section, and see how NB distribution fits to non-zero portion of genes. We first take the non-zero portion of the genes.

Fold change in mean in non-zero portion

Change WRT condition in G6

Within G6, we compare mean (here refers to non-zero mean) across biological condition groups. Specifically, we saved the previous DE analysis results using edgeR, on counts containing zeros. We call all genes with \(\log(FC) >= 0\) as “up” genes, and \(\log(FC) < 0\) as “down” genes. The top 50 “up” and “down” genes are still determined by the previous DE containing zeros.

######  Changes in MEAN non-zero gene counts  ######
               top50 up top50 down 100 least DE
Non-progressor   2169.9     4497.1       2196.1
Progressor       3914.2     3786.5       2085.1
######  Changes in MEDIAN non-zero gene counts  ######
               top50 up top50 down 100 least DE
Non-progressor      609       2236        474.5
Progressor          961       1834        471.0

Conclusions:

  • Biological fold change (in non-zero portion) comparing average counts in top genes is about 1.2-1.8 (mean).
  • O counts did not strongly affect biological signal in terms of average counts in top genes .

Change WRT batch in non-progressors

Similarly, we compare non-zero mean in top genes across batches within “Non-progressors” of Africa and G6 studies. Here “top genes” refer to top gene lists from previous DE within control samples comparing batches.

######  Changes in MEAN non-zero gene counts  ######
       top50 up top50 down 100 least DE
Africa   2072.8     4110.2        446.7
G6       6834.0     3530.7        609.6
######  Changes in MEDIAN non-zero gene counts  ######
       top50 up top50 down 100 least DE
Africa      473       2413           30
G6         1600       2054           34

Conclusions:

  • Mean batch effect fold change (non-zero portion) comparing average counts in top genes ranges from 1.16-3.3 (mean).
  • O counts did not strongly affect mean batch effect in terms of average counts in top genes.

Batch mean with 0 counts removed

Median (of all genes) gene-wise mean after removing zeros:

               Africa    G6 Brazil1
Non-progressor 118.62 155.7   35.33
Progressor     109.31 173.2   33.94

Scaled by that of Africa:

               Africa   G6 Brazil1
Non-progressor      1 1.31    0.30
Progressor          1 1.58    0.31

Batch dispersion with 0 counts removed

Dispersion estimates are more likely impacted by 0 counts. We re-estimate the dispersions in each batch, using non-zero portion of each gene. Then we compare the dispersion estimates across batches.

####  Statistics about dispersion estimates (from NON-ZERO portions) from the two batches  ####
             Africa     G6  India Brazil_1 Brazil_2
min disp.    0.0000 0.0000 0.0000   0.0000   0.0000
median disp. 0.1293 0.1739 0.1176   0.5544   0.1708
mean disp.   0.1885 0.2359 0.1601   0.5460   0.2548
max disp.    5.0019 4.1344 3.1316   3.7155   4.8316

Conclusions:

  • Mean dispersion of Brazil batch 1 is roughly 3.4 times that of India.
  • The absolute value of max gene-wise dispersion are reduced after 0 counts are removed.
  • In this report, dispersion are calculated by different methods before and after removing 0 counts. Not directly comparable.
  • We show in another analysis (TB_run_nonzero_disps.R) that the difference in dispersion is reduced after removing 0s.

Batch variance with 0 counts removed

Median gene-wise variance after removing zeros:

                Africa       G6 Brazil1
Non-progressor 4871.43  8110.23  964.11
Progressor     4561.47 11948.42 1571.00

Scaled by that of Africa:

               Africa   G6 Brazil1
Non-progressor      1 1.66    0.20
Progressor          1 2.62    0.34

Is there a difference in zero portions across batches?

Another question related to batch effect, is whether there is any difference in the percentage of 0 counts in a gene between two batches.

Conclusions:

  • There isn’t an obvious difference in zero fractions between batches (aside from Brazil batch 2 which is too small).

Goodness of fit for NB distribution to non-zero portion of genes

It is difficult to evaluate quantitatively the goodness-of-fit of NB distribution on data. Instead, we generate Q-Q plots for 100 randomly selected genes, comparing data with NB distribution using ML estimated parameters. We generate these plots within G6/Africa, for cases and control samples separately. Figures are stored under {output_dir}/qqplots_{Study}/.

More justification for having different dispersion parameter for different batches

Finally, a very important assumption of ComBat-seq model (compared to adding batch covariates in linear model of edgeR and DESeq), is that having a different dispersion parameter for each batch is beneficial for DE performance. As argued by many, if not all, of these papers, accurate estimation of dispersion paramters are important for DE detection. As we have seen above, there is some difference in dispersion distribution across batches. If dispersion estimates within each batch and using the whole study are not consistent with each other, then it is justification that we may need different dipsersion parameter for different batches, and it could be good for DE.

Here we generate scatter plots comparing dispersion estimates within each batch to estimates from whole dataset (including batch as a covariate in whole study).

In Brazil

Gene-wise dispersion estimates

Trended dispersion estimates

Africa VS G6

Gene-wise dispersion estimates

Trended dispersion estimates

Brazil Batch 1 VS India

Gene-wise dispersion estimates

Trended dispersion estimates

Session info

R version 3.5.1 (2018-07-02)
Platform: x86_64-apple-darwin15.6.0 (64-bit)
Running under: macOS High Sierra 10.13.6

Matrix products: default
BLAS: /System/Library/Frameworks/Accelerate.framework/Versions/A/Frameworks/vecLib.framework/Versions/A/libBLAS.dylib
LAPACK: /Library/Frameworks/R.framework/Versions/3.5/Resources/lib/libRlapack.dylib

locale:
[1] en_US.UTF-8/en_US.UTF-8/en_US.UTF-8/C/en_US.UTF-8/en_US.UTF-8

attached base packages:
[1] parallel  stats4    stats     graphics  grDevices utils     datasets  methods   base     

other attached packages:
 [1] MASS_7.3-51                 ggdendro_0.1-20             scales_1.0.0                gridExtra_2.3              
 [5] reshape2_1.4.3              ggplot2_3.0.0               dendextend_1.9.0            edgeR_3.22.5               
 [9] limma_3.36.5                DESeq2_1.20.0               SummarizedExperiment_1.10.1 DelayedArray_0.6.6         
[13] BiocParallel_1.14.2         matrixStats_0.54.0          Biobase_2.40.0              GenomicRanges_1.32.7       
[17] GenomeInfoDb_1.16.0         IRanges_2.14.12             S4Vectors_0.18.3            BiocGenerics_0.26.0        

loaded via a namespace (and not attached):
 [1] bitops_1.0-6           bit64_0.9-7            RColorBrewer_1.1-2     rprojroot_1.3-2        prabclus_2.2-6        
 [6] tools_3.5.1            backports_1.1.2        R6_2.3.0               rpart_4.1-13           Hmisc_4.1-1           
[11] DBI_1.0.0              lazyeval_0.2.1         colorspace_1.3-2       trimcluster_0.1-2.1    nnet_7.3-12           
[16] withr_2.1.2            tidyselect_0.2.5       bit_1.1-14             compiler_3.5.1         htmlTable_1.12        
[21] labeling_0.3           diptest_0.75-7         checkmate_1.8.5        DEoptimR_1.0-8         mvtnorm_1.0-8         
[26] robustbase_0.93-3      genefilter_1.62.0      stringr_1.3.1          digest_0.6.18          foreign_0.8-71        
[31] rmarkdown_1.10         XVector_0.20.0         base64enc_0.1-3        pkgconfig_2.0.2        htmltools_0.3.6       
[36] htmlwidgets_1.3        rlang_0.3.0            rstudioapi_0.8         RSQLite_2.1.1          bindr_0.1.1           
[41] jsonlite_1.5           mclust_5.4.1           acepack_1.4.1          dplyr_0.7.7            RCurl_1.95-4.11       
[46] magrittr_1.5           modeltools_0.2-22      GenomeInfoDbData_1.1.0 Formula_1.2-3          Matrix_1.2-14         
[51] Rcpp_0.12.19           munsell_0.5.0          viridis_0.5.1          stringi_1.2.4          whisker_0.3-2         
[56] yaml_2.2.0             zlibbioc_1.26.0        flexmix_2.3-14         plyr_1.8.4             grid_3.5.1            
[61] blob_1.1.1             crayon_1.3.4           lattice_0.20-35        splines_3.5.1          annotate_1.58.0       
[66] locfit_1.5-9.1         knitr_1.20             pillar_1.3.0           fpc_2.1-11.1           geneplotter_1.58.0    
[71] XML_3.98-1.16          glue_1.3.0             evaluate_0.12          latticeExtra_0.6-28    data.table_1.11.8     
[76] gtable_0.2.0           purrr_0.2.5            kernlab_0.9-27         assertthat_0.2.0       xtable_1.8-3          
[81] viridisLite_0.3.0      class_7.3-14           survival_2.42-6        tibble_1.4.2           AnnotationDbi_1.42.1  
[86] memoise_1.1.0          bindrcpp_0.2.2         cluster_2.0.7-1       

References

LS0tCnRpdGxlOiAiRXhwbG9yYXRpb24gb2YgcmVhbCBidWxrIFJOQS1zZXEgZGF0YXNldHMiCnN1YnRpdGxlOiAiVEIgZGF0YXNldHMiCmF1dGhvcjogWXVxaW5nIFpoYW5nCmRhdGU6ICJgciBTeXMuRGF0ZSgpYCIKb3V0cHV0OgogIGh0bWxfbm90ZWJvb2s6CiAgICB0aGVtZTogdW5pdGVkCiAgICB0b2M6IHllcwpiaWJsaW9ncmFwaHk6IHJlZnMuYmliCi0tLQoKIyMgSW50cm9kdWN0aW9uCgpUaGlzIGlzIGEgY3VyYXRlZCBkYXRhc2V0IGNvbnRhaW5pbmcgdGhlIEFmcmljYSwgQnJhemlsLCBJbmRpYSwgYW5kIHRoZSBHNiBkYXRhc2V0cywgd2hpY2ggYXJlIGFsbCBUQiBkYXRhc2V0cyB3aXRoIGFjdGl2ZSBUQiBwYXRpZW50cywgcGF0aWVudHMgdGhhdCB3aWxsIHByb2dyZXNzIHRvIGFjdGl2ZSBUQiwgYW5kIHBlb3BsZSB3aXRoIFRCIGluZmVjdGlvbiB3aG8gZG9u4oCZdCBwcm9ncmVzcy4gVGhlcmUgaXMgYSBiYXRjaCBlZmZlY3QgZXNwZWNpYWxseSB3aXRoIHRoZSBCcmF6aWwgZGF0YS4gVGhpcyBvYmplY3QgaXMgYSBTdW1tYXJpemVkRXhwZXJpbWVudCB3aXRoIDcgYXNzYXlzLiBUaGUg4oCYY29tYmF04oCZIGFzc2F5IHdhcyBtYWRlIGJ5IHJ1bm5pbmcgdGhlIGxvZ3RwbSB2YWx1ZXMgdGhyb3VnaCBjb21iYXQgd2l0aCDigJhTZXF1ZW5jaW5nQmF0Y2jigJkgYXMgdGhlIGJhdGNoIGFuZCDigJhMYWJlbOKAmSBhcyB0aGUgY292YXJpYXRlLiDigJxMYWJlbOKAnSBpcyB0aGUgY29uZGl0aW9uIE5vbi1wcm9ncmVzc29yLCBQcm9ncmVzc29yLCBhbmQgQWN0aXZlLgoKCiMjIyBPdmVyYWxsIGRlc2lnbgoKVGhlIGNvbWJpbmVkIGRhdGFzZXQgY29udGFpbnMgNCBzdHVkaWVzLCBpbiB3aGljaCBCcmF6aWwgZGF0YXNldCBoYXMgMiBiYXRjaGVzIHdpdGhpbiB0aGUgc3R1ZHk6CgorIEFmcmljYTogMTk3IHNhbXBsZXMsICgxMDQgTm9uLXByb2dyZXNzb3IsIDc3IFByb2dyZXNzb3IsIDE2IEFjdGl2ZSkKKyBCcmF6aWw6IDUxIHNhbXBsZXMsICgyMSBOb24tcHJvZ3Jlc3NvciwgMTYgUHJvZ3Jlc3NvciwgMTQgQWN0aXZlKQogICAgLSBCYXRjaCAxOiAzOSBzYW1wbGVzLCAoOSBOb24tcHJvZ3Jlc3NvciwgMTYgUHJvZ3Jlc3NvciwgMTQgQWN0aXZlKQogICAgLSBCYXRjaCAyOiAxMiBzYW1wbGVzLCAoMTIgTm9uLXByb2dyZXNzb3IsIDAgUHJvZ3Jlc3NvciwgMCBBY3RpdmUpCisgRzY6IDM5OSBzYW1wbGVzLCAoMzA0IE5vbi1wcm9ncmVzc29yLCA5NSBQcm9ncmVzc29yLCAwIEFjdGl2ZSkKKyBJbmRpYTogNDQgc2FtcGxlcywgKDE5IE5vbi1wcm9ncmVzc29yLCAwIFByb2dyZXNzb3IsIDI1IEFjdGl2ZSkKCioqTm90ZSoqOiBHZW5kZXIgaXMgYW4gaW1wb3J0YW50IGZhY3RvciBpbiB0aGlzIHN0dWR5LgoKCiMjIyBMb2FkIGRhdGEgJiBzdW1tYXJpemUgYmFzaWMgaW5mbwoKYGBge3IsIGVjaG89RkFMU0UsIHJlc3VsdHM9J2hpZGUnfQpybShsaXN0PWxzKCkpCm91dHB1dF9kaXIgPC0gIn4vR29vZ2xlIERyaXZlL0NvbUJhdF9zZXEvcmVhbF9kYXRhX2V4YW1wbGUvUk5Bc2VxL1RCIgpzYXBwbHkoYygiU3VtbWFyaXplZEV4cGVyaW1lbnQiLCAiREVTZXEyIiwgImVkZ2VSIiwgImRlbmRleHRlbmQiLCAiZ2dwbG90MiIsICJyZXNoYXBlMiIsIAogICAgICAgICAiZ3JpZEV4dHJhIiwgInNjYWxlcyIsICJnZ2RlbmRybyIsICJNQVNTIiksIHJlcXVpcmUsIGNoYXJhY3Rlci5vbmx5PVRSVUUpCgojIyMjICBMb2FkIGRhdGEKcmRzX29iaiA8LSByZWFkUkRTKGZpbGUucGF0aChvdXRwdXRfZGlyLCAiY29tYmluZWQucmRzIikpCmN0cyA8LSBhc3NheXMocmRzX29iaikkY291bnRzCiMgYmF0Y2ggaW5kaWNhdG9yCmJhdGNoIDwtIGNvbERhdGEocmRzX29iaikkU2VxdWVuY2luZ0JhdGNoCiMgY29uZGl0aW9uIGluZGljYXRvcgpncm91cCA8LSBjb2xEYXRhKHJkc19vYmopJExhYmVsCmBgYAoKQWZ0ZXIgbG9hZGluZyB0aGUgZGF0YSwgd2UgY2FsY3VsYXRlIGEgZmV3IGJhc2ljIHN0YXRpc3RpY3Mgb2YgdGhlIGRhdGFzZXQuCgpgYGB7ciwgZWNobz1GQUxTRX0KY2F0KCIjIyMjIyMgIFNhbXBsZXMgICMjIyMjIyNcbiIpCmNhdCgiLSBUb3RhbCBudW1iZXIgb2Ygc2FtcGxlczpcbiIpCnByaW50KG5jb2woY3RzKSkKCmNhdCgiXG4tIE51bWJlciBvZiBzYW1wbGVzIGluIGNvbmRpdGlvbiBncm91cHM6XG4iKQpwcmludCh0YWJsZShncm91cCkpCgpjYXQoIlxuLSBOdW1iZXIgb2Ygc2FtcGxlcyBpbiBiYXRjaGVzOlxuIikKcHJpbnQodGFibGUoYmF0Y2gpKQpjYXQoIlxuSW4gZWFjaCBiYXRjaCBzZXBhcmF0ZWx5OlxuIikKbl9iYXRjaGVzIDwtIGxhcHBseShsZXZlbHMoYmF0Y2gpLCBmdW5jdGlvbihjdXJyX2JhdGNoKXsKICB0YWJsZShncm91cFtiYXRjaD09Y3Vycl9iYXRjaF0pCn0pCm5fYmF0Y2hlcyA8LSBkby5jYWxsKHJiaW5kLCBuX2JhdGNoZXMpCnJvd25hbWVzKG5fYmF0Y2hlcykgPC0gbGV2ZWxzKGJhdGNoKQpwcmludChuX2JhdGNoZXMpCgoKY2F0KCJcblxuIyMjIyMjICBHZW5lcyAgIyMjIyMjI1xuIikKY2F0KCItIFRvdGFsIG51bWJlciBvZiBnZW5lczpcbiIpCnByaW50KG5yb3coY3RzKSkKCmNhdCgiXG4tIE51bWJlciBvZiBnZW5lcyB3aXRoIDAgY291bnRzOlxuIikKZ2VuZV9yb3dfd2l0aF96ZXJvcyA8LSBhcHBseShjdHMsIDEsIGZ1bmN0aW9uKHgpe2FueSh4PT0wKX0pCmNhdChjKHN1bShnZW5lX3Jvd193aXRoX3plcm9zKSwgcGVyY2VudChzdW0oZ2VuZV9yb3dfd2l0aF96ZXJvcykvbnJvdyhjdHMpKSkpCgpjYXQoIlxuXG4tIE51bWJlciBvZiBnZW5lcyB3aXRoIG1heGltdW0gMTAgY291bnRzOlxuIikKZ2VuZV9yb3dfbG93IDwtIGFwcGx5KGN0cywgMSwgZnVuY3Rpb24oeCl7YWxsKHg8PTEwKX0pCmNhdChjKHN1bShnZW5lX3Jvd19sb3cpLCBwZXJjZW50KHN1bShnZW5lX3Jvd19sb3cpL25yb3coY3RzKSkpKQoKY2F0KCJcblxuLSBOdW1iZXIgb2YgZ2VuZXMgd2l0aCBPTkxZIDBzOlxuIikKZ2VuZV9hbGxfemVyb3MgPC0gYXBwbHkoY3RzLCAxLCBmdW5jdGlvbih4KXthbGwoeD09MCl9KQpjYXQoYyhzdW0oZ2VuZV9hbGxfemVyb3MpLCBwZXJjZW50KHN1bShnZW5lX2FsbF96ZXJvcykvbnJvdyhjdHMpKSkpCgoKY2F0KCJcblxuXG4jIyMjIyMgIENvdW50cyAgIyMjIyMjI1xuIikKY2F0KCItIFJhbmdlIG9mIGNvdW50IGluIHdob2xlIGRhdGFzZXQ6XG4iKQpwcmludChyb3VuZChyYW5nZShjdHMpLCAzKSkKCmNhdCgiXG4tIEF2ZXJhZ2UgY291bnQgaW4gd2hvbGUgZGF0YXNldDpcbiIpCnByaW50KHBhc3RlKCJNZWFuOiIsIHJvdW5kKG1lYW4oY3RzKSwgMykpKQpwcmludChwYXN0ZSgiTWVkaWFuOiIsIHJvdW5kKG1lZGlhbihjdHMpLCAzKSkpCgpybShnZW5lX3Jvd193aXRoX3plcm9zLCBnZW5lX3Jvd19sb3csIGdlbmVfYWxsX3plcm9zKQpgYGAKClRoZXJlIGFyZSBubyBnZW5lcyB3aXRoIG9ubHkgemVybyB2YWx1ZXMgYWNyb3NzIGFsbCBzYW1wbGVzIChwcm9iYWJseSBiZWNhdXNlIG9mIGNsZWFuaW5nIGluIHRoZSBjdXJhdGlvbiBzdGFnZSkuIFRoZSBmaWd1cmUgYmVsb3cgc2hvd3MgZGlzdHJpYnV0aW9uIG9mIHBlcmNlbnRhZ2VzIG9mIHplcm8gY291bnRzIGZvciB0aGUgcmVtYWluaW5nIGdlbmVzIChlYWNoIGRhdGEgcG9pbnQgcmVwcmVzZW50cyBhIGdlbmUsIGkuZS4sIGhvdyBtYW55IHplcm9zIGFyZSB0aGVyZSBpbiBlYWNoIGdlbmUpLgoKYGBge3IsIGVjaG89RkFMU0V9Cm5femVyb3NfaW5fZ2VuZXMgPC0gYXBwbHkoY3RzLCAxLCBmdW5jdGlvbih4KXtsZW5ndGgod2hpY2goeD09MCkpfSkKcGVyY2VudF96ZXJvc19pbl9nZW5lcyA8LSBuX3plcm9zX2luX2dlbmVzIC8gbmNvbChjdHMpCnBlcmNlbnRfemVyb3NfZGYgPC0gZGF0YS5mcmFtZShnZW5lcz1yb3duYW1lcyhjdHMpLCB2YWx1ZT1wZXJjZW50X3plcm9zX2luX2dlbmVzKQoKYmlubmVkX2N0cyA8LSBoaXN0KHBlcmNlbnRfemVyb3NfaW5fZ2VuZXMsIGJyZWFrcz0xMCwgcGxvdD1GQUxTRSkkY291bnRzIApiaW5uZWRfcHJvcG9ydGlvbnMgPC0gYmlubmVkX2N0cyAvIHN1bShiaW5uZWRfY3RzKQpuYW1lcyhiaW5uZWRfcHJvcG9ydGlvbnMpIDwtIHBhc3RlMCgiPCIsIHBlcmNlbnQoc2VxKGZyb209MC4xLCB0bz0xLCBieT0wLjEpKSkgIApjYXQoIiMjIyMjIyAgUHJvcG9ydGlvbiBvZiBnZW5lcyB3aXRoIFglIHplcm9zIGFjcm9zcyBzYW1wbGVzICAjIyMjIyMjXG4iKQpwcmludChyb3VuZChiaW5uZWRfcHJvcG9ydGlvbnMsMykpCgpnZ3Bsb3QocGVyY2VudF96ZXJvc19kZiwgYWVzKDAsIHZhbHVlKSkgKyAKICAgICAgZ2VvbV92aW9saW4oKSArCiAgICAgIGdlb21fYm94cGxvdChhZXMoMC43LCB2YWx1ZSksIHdpZHRoPTAuMTUpICsKICAgICAgY29vcmRfZmxpcCgpICsKICAgICAgYW5ub3RhdGUoZ2VvbT0idGV4dCIsIGxhYmVsPXBlcmNlbnQobWVkaWFuKHBlcmNlbnRfemVyb3NfZGYkdmFsdWUpKSwgeD0wLjg1LCB5PW1lZGlhbihwZXJjZW50X3plcm9zX2RmJHZhbHVlKSkgKwogICAgICBsYWJzKHk9IiUgWmVyb3MiLCB0aXRsZT0iUHJvcG9ydGlvbiBvZiB6ZXJvcyBhY3Jvc3Mgc2FtcGxlcyBmb3IgdGhlIHJlbWFpbmluZyBnZW5lcyIpICsKICAgICAgdGhlbWUoYXhpcy50aXRsZS55PWVsZW1lbnRfYmxhbmsoKSkjLCBheGlzLnRleHQueT1lbGVtZW50X2JsYW5rKCkpCmBgYAoKYGBge3IsIGVjaG89RkFMU0V9CnJtKG5femVyb3NfaW5fZ2VuZXMsIHBlcmNlbnRfemVyb3NfaW5fZ2VuZXMsIHBlcmNlbnRfemVyb3NfZGYpCmBgYAoKCgojIyBFeGlzdGVuY2Ugb2YgYmF0Y2ggZWZmZWN0IHsudGFic2V0fQoKSW4gdGhpcyBtZXJnZWQgZGF0YXNldCwgdGhlcmUgYXJlIGJvdGggInN0dWR5IGVmZmVjdHMiIGFjcm9zcyB0aGUgNCBzdHVkaWVzICh0YXJnZXRpbmcgZGlmZmVyZW50IHBvcHVsYXRpb25zKSwgYW5kIGJhdGNoIGVmZmVjdCB3aXRoaW4gdGhlIHNhbWUgc3R1ZHkgKEJyYXppbCBkYXRhc2V0KS4KCiMjIyBQQ0EKCmBgYHtyLCBlY2hvPUZBTFNFLCBmaWcuaGVpZ2h0PTMuNSwgZmlnLndpZHRoPTV9CnBjYV9vYmogPC0gcGxvdFBDQShERVNlcVRyYW5zZm9ybShyZHNfb2JqKSwgaW50Z3JvdXA9YygiU2VxdWVuY2luZ0JhdGNoIiwgIkxhYmVsIiwgIlNleCIsICJEYXRhc2V0IikpIApwX2JhdGNoIDwtIGdncGxvdChwY2Ffb2JqJGRhdGEsIGFlcyh4PVBDMSwgeT1QQzIsIGNvbG9yPVNlcXVlbmNpbmdCYXRjaCkpICsKICBnZW9tX3BvaW50KCkgKyAKICBsYWJzKHg9c3ByaW50ZigiUEMxOiAlcyBWYXJpYW5jZSIsIHBlcmNlbnQocGNhX29iaiRwbG90X2VudiRwZXJjZW50VmFyWzFdKSksCiAgICAgICB5PXNwcmludGYoIlBDMjogJXMgVmFyaWFuY2UiLCBwZXJjZW50KHBjYV9vYmokcGxvdF9lbnYkcGVyY2VudFZhclsyXSkpLAogICAgICAgdGl0bGU9IlBDQTogc2FtcGxlcyBjb2xvcmVkIGJ5IEJhdGNoIikKcF9jb25kIDwtIGdncGxvdChwY2Ffb2JqJGRhdGEsIGFlcyh4PVBDMSwgeT1QQzIsIGNvbG9yPUxhYmVsKSkgKwogIGdlb21fcG9pbnQoKSArIAogIGxhYnMoeD1zcHJpbnRmKCJQQzE6ICVzIFZhcmlhbmNlIiwgcGVyY2VudChwY2Ffb2JqJHBsb3RfZW52JHBlcmNlbnRWYXJbMV0pKSwKICAgICAgIHk9c3ByaW50ZigiUEMyOiAlcyBWYXJpYW5jZSIsIHBlcmNlbnQocGNhX29iaiRwbG90X2VudiRwZXJjZW50VmFyWzJdKSksCiAgICAgICB0aXRsZT0iUENBOiBzYW1wbGVzIGNvbG9yZWQgYnkgQ29uZGl0aW9uIikKcF9zdHVkaWVzIDwtIGdncGxvdChwY2Ffb2JqJGRhdGEsIGFlcyh4PVBDMSwgeT1QQzIsIGNvbG9yPURhdGFzZXQpKSArCiAgZ2VvbV9wb2ludCgpICsgCiAgbGFicyh4PXNwcmludGYoIlBDMTogJXMgVmFyaWFuY2UiLCBwZXJjZW50KHBjYV9vYmokcGxvdF9lbnYkcGVyY2VudFZhclsxXSkpLAogICAgICAgeT1zcHJpbnRmKCJQQzI6ICVzIFZhcmlhbmNlIiwgcGVyY2VudChwY2Ffb2JqJHBsb3RfZW52JHBlcmNlbnRWYXJbMl0pKSwKICAgICAgIHRpdGxlPSJQQ0E6IHNhbXBsZXMgY29sb3JlZCBieSBTdHVkaWVzIikKcF9zZXggPC0gZ2dwbG90KHBjYV9vYmokZGF0YSwgYWVzKHg9UEMxLCB5PVBDMiwgY29sb3I9U2V4KSkgKwogIGdlb21fcG9pbnQoKSArIAogIGxhYnMoeD1zcHJpbnRmKCJQQzE6ICVzIFZhcmlhbmNlIiwgcGVyY2VudChwY2Ffb2JqJHBsb3RfZW52JHBlcmNlbnRWYXJbMV0pKSwKICAgICAgIHk9c3ByaW50ZigiUEMyOiAlcyBWYXJpYW5jZSIsIHBlcmNlbnQocGNhX29iaiRwbG90X2VudiRwZXJjZW50VmFyWzJdKSksCiAgICAgICB0aXRsZT0iUENBOiBzYW1wbGVzIGNvbG9yZWQgYnkgU2V4IikKZ3JpZC5hcnJhbmdlKHBfYmF0Y2gsIHBfY29uZCwgcF9zdHVkaWVzLCBwX3NleCwgbnJvdz0yLCBuY29sPTIpCmBgYAoKCiMjIyBQQ0EgKEJyYXppbCBvbmx5KQoKYGBge3IsIGVjaG89RkFMU0UsIGZpZy5oZWlnaHQ9MiwgZmlnLndpZHRoPTV9CnJkc19icmF6aWwgPC0gcmRzX29ialssIHJkc19vYmokRGF0YXNldD09IkJyYXppbCJdCgpwY2Ffb2JqX2JyYXppbCA8LSBwbG90UENBKERFU2VxVHJhbnNmb3JtKHJkc19icmF6aWwpLCBpbnRncm91cD1jKCJTZXF1ZW5jaW5nQmF0Y2giLCAiTGFiZWwiKSkgCnBiX2JhdGNoIDwtIGdncGxvdChwY2Ffb2JqX2JyYXppbCRkYXRhLCBhZXMoeD1QQzEsIHk9UEMyLCBjb2xvcj1TZXF1ZW5jaW5nQmF0Y2gpKSArCiAgZ2VvbV9wb2ludCgpICsgCiAgbGFicyh4PXNwcmludGYoIlBDMTogJXMgVmFyaWFuY2UiLCBwZXJjZW50KHBjYV9vYmpfYnJhemlsJHBsb3RfZW52JHBlcmNlbnRWYXJbMV0pKSwKICAgICAgIHk9c3ByaW50ZigiUEMyOiAlcyBWYXJpYW5jZSIsIHBlcmNlbnQocGNhX29ial9icmF6aWwkcGxvdF9lbnYkcGVyY2VudFZhclsyXSkpLAogICAgICAgdGl0bGU9IlBDQTogc2FtcGxlcyBjb2xvcmVkIGJ5IEJhdGNoIikKcGJfY29uZCA8LSBnZ3Bsb3QocGNhX29ial9icmF6aWwkZGF0YSwgYWVzKHg9UEMxLCB5PVBDMiwgY29sb3I9TGFiZWwpKSArCiAgZ2VvbV9wb2ludCgpICsgCiAgbGFicyh4PXNwcmludGYoIlBDMTogJXMgVmFyaWFuY2UiLCBwZXJjZW50KHBjYV9vYmpfYnJhemlsJHBsb3RfZW52JHBlcmNlbnRWYXJbMV0pKSwKICAgICAgIHk9c3ByaW50ZigiUEMyOiAlcyBWYXJpYW5jZSIsIHBlcmNlbnQocGNhX29ial9icmF6aWwkcGxvdF9lbnYkcGVyY2VudFZhclsyXSkpLAogICAgICAgdGl0bGU9IlBDQTogc2FtcGxlcyBjb2xvcmVkIGJ5IENvbmRpdGlvbiIpCmdyaWQuYXJyYW5nZShwYl9iYXRjaCwgcGJfY29uZCwgbmNvbD0yKQpgYGAKCgojIyMgRGVuZHJvZ3JhbXMgKEJyYXppbCBvbmx5KQoKYGBge3IsIGVjaG89RkFMU0UsIGZpZy5oZWlnaHQ9Mi44LCBmaWcud2lkdGg9NS41fQpjb3VudHNfbm9ybSA8LSBzY2FsZSh0KGFzc2F5KHJkc19icmF6aWwsImNvdW50cyIpKSwgY2VudGVyPVRSVUUsIHNjYWxlPVRSVUUpCmhjIDwtIGhjbHVzdChkaXN0KGNvdW50c19ub3JtKSkKZGVuZCA8LSBhcy5kZW5kcm9ncmFtKGhjKQpkZGF0YSA8LSBkZW5kcm9fZGF0YShkZW5kLCB0eXBlPSJyZWN0YW5nbGUiKQoKbWV0YV9pbmZvIDwtIGRhdGEuZnJhbWUoY29sRGF0YShyZHNfYnJhemlsKVssIGMoIlNlcXVlbmNpbmdCYXRjaCIsICJMYWJlbCIpXSwgc2FtcGxlPWNvbG5hbWVzKHJkc19icmF6aWwpKQp0bXAgPC0gbWVyZ2UoeD1kZGF0YSRsYWJlbHMsIHk9bWV0YV9pbmZvLCBieS54PSJsYWJlbCIsIGJ5Lnk9InNhbXBsZSIpCgpwZF9iYXRjaCA8LSBnZ3Bsb3Qoc2VnbWVudChkZGF0YSkpICsgCiAgZ2VvbV9zZWdtZW50KGFlcyh4PXgsIHk9eSwgeGVuZD14ZW5kLCB5ZW5kPXllbmQpKSArIAogIGNvb3JkX2ZsaXAoKSArIHNjYWxlX3lfcmV2ZXJzZSgpICsKICBzY2FsZV9jb2xvcl9tYW51YWwodmFsdWVzPWMoJyNFNjlGMDAnLCAnIzU2QjRFOScpKSArCiAgZ2VvbV90ZXh0KGRhdGE9dG1wLCBhZXMobGFiZWw9dG1wJGxhYmVsLCB4PXgsIHk9LTEwLCBjb2xvdXI9U2VxdWVuY2luZ0JhdGNoKSkgKwogIGxhYnMoeD0iIiwgeT0iIiwgdGl0bGU9IkNsdXN0ZXJpbmc6IHNhbXBsZXMgY29sb3JlZCBieSBCYXRjaCIpCnBkX2NvbmQgPC0gZ2dwbG90KHNlZ21lbnQoZGRhdGEpKSArIAogIGdlb21fc2VnbWVudChhZXMoeD14LCB5PXksIHhlbmQ9eGVuZCwgeWVuZD15ZW5kKSkgKyAKICBjb29yZF9mbGlwKCkgKyBzY2FsZV95X3JldmVyc2UoKSArCiAgZ2VvbV90ZXh0KGRhdGE9dG1wLCBhZXMobGFiZWw9dG1wJGxhYmVsLCB4PXgsIHk9LTEwLCBjb2xvdXI9TGFiZWwpKSArCiAgbGFicyh4PSIiLCB5PSIiLCB0aXRsZT0iQ2x1c3RlcmluZzogc2FtcGxlcyBjb2xvcmVkIGJ5IENvbmRpdGlvbiIpCmdyaWQuYXJyYW5nZShwZF9iYXRjaCwgcGRfY29uZCwgbmNvbD0yKQoKcm0oY291bnRzX25vcm0sIGRkYXRhLCBkZW5kLCBoYywgcF9iYXRjaCwgcF9jb25kLCBwX3N0dWRpZXMsIHBfc2V4LCBwY2Ffb2JqLCBwZF9iYXRjaCwgcGRfY29uZCwgdG1wLAogICBwY2Ffb2JqX2JyYXppbCwgcGJfYmF0Y2gsIHBiX2NvbmQpCmBgYAoKCgojIyBMaWJyYXJ5IHNpemUKCk5leHQsIHdlIHRha2UgYSBsb29rIGF0IHRoZSBvYnNlcnZlZCBsaWJyYXJ5IHNpemVzIG9mIHNhbXBsZXMsIGFuZCB0byBzZWUgaWYgdGhlcmUgaXMgYSBkaWZmZXJlbmNlIGluIGxpYnJhcnkgc2l6ZSBhY3Jvc3MgYmF0Y2hlcy4KCmBgYHtyLCBlY2hvPUZBTFNFfQojIyMgIERpc3RyaWJ1dGlvbiBvZiBsaWJyYXJ5IHNpemUKbGliX3NpemVzIDwtIGNvbFN1bXMoY3RzKQpjYXQoIlJhbmdlIG9mIG9ic2VydmVkIGxpYnJhcnkgc2l6ZXMgYWNyb3NzIHNhbXBsZXM6XG4iKQpwcmludChzY2llbnRpZmljKHJhbmdlKGxpYl9zaXplcykpKQpgYGAKCmBgYHtyLCBlY2hvPUZBTFNFLCBmaWcuaGVpZ2h0PTIsIGZpZy53aWR0aD00LjV9CmxpYl9zaXplc19kZiA8LSBkYXRhLmZyYW1lKGxpYl9zaXplcz1saWJfc2l6ZXMsIGJhdGNoPWJhdGNoKQoKIyBvdmVyYWxsIHNhbXBsZSBsaWJyYXJ5IHNpemVzCnBsaWIxIDwtIGdncGxvdChsaWJfc2l6ZXNfZGYsIGFlcyh4PWxpYl9zaXplcykpICsgCiAgZ2VvbV9oaXN0b2dyYW0oYmlucz1yb3VuZChuY29sKHJkc19vYmopLzUpKSArCiAgZ2VvbV92bGluZShhZXMoeGludGVyY2VwdD1tZWFuKGxpYl9zaXplcykpLCBjb2xvcj0icmVkIiwgbGluZXR5cGU9ImRhc2hlZCIsIHNpemU9MSkgKwogIGFubm90YXRlKGdlb209InRleHQiLCB4PW1lYW4obGliX3NpemVzKSwgeT1tYXgoaGlzdChsaWJfc2l6ZXMsIHBsb3Q9RkFMU0UpJGNvdW50cykrMSwgCiAgICAgICAgICAgbGFiZWw9c2NpZW50aWZpYyhtZWFuKGxpYl9zaXplcykpLCBjb2xvcj0icmVkIikgKwogIGxhYnMoeD0iTGlicmFyeSBzaXplcyBpbiBzYW1wbGVzIiwgeT0iTnVtYmVyIG9mIHNhbXBsZXMiLCAKICAgICAgIHRpdGxlPSJEaXN0cmlidXRpb24gb2Ygb2JzZXJ2ZWQgbGlicmFyeSBzaXplcyIpIAoKIyBib3hwbG90IGNvbXBhcmluZyBkaXN0cmlidXRpb24gb2YgbGlicmFyeSBzaXplIGFjcm9zcyBiYXRjaGVzCnBsaWIyIDwtIGdncGxvdChsaWJfc2l6ZXNfZGYsIGFlcyh4PWJhdGNoLCB5PWxpYl9zaXplcywgZmlsbD1iYXRjaCkpICsgCiAgZ2VvbV9ib3hwbG90KCkgKwogIGxhYnMoeD0iIiwgeT0iTGlicmFyeSBzaXplcyIsIHRpdGxlPSJDb21wYXJlIGxpYnJhcnkgc2l6ZXMgYWNyb3NzIGJhdGNoIikgCgpncmlkLmFycmFuZ2UocGxpYjEsIHBsaWIyLCBuY29sPTIpCgpybShwbGliMSwgcGxpYjIpCmBgYAoKCgojIyBHZW5lIGV4cHJlc3Npb24gZGlzdHJpYnV0aW9uCgpPdXIgbmV4dCBzdGVwIGlzIHRvIGludGVycm9nYXRlIHRoZSBnZW5lIGV4cHJlc3Npb24gZGlzdHJpYnV0aW9ucy4gCgo8IS0tCldlIGZpcnN0IHNpbXBseSBwbG90IHRoZSBjb3VudHMsIENQTSwgYW5kIGxvZzJDUE0gb2YgMjAgcmFuZG9tbHkgY2hvc2VuIGdlbmVzIGluIHRoZSBkYXRhc2V0LiBUaGVzZSBmaWd1cmVzIGFyZSBzdG9yZWQgdW5kZXIgZGlyZWN0b3J5IHNwZWNpZmllZCBieSB7b3V0cHV0X2Rpcn0vcmFuZEdwbG90cy8uICAKLS0+IAoKYGBge3IsIGVjaG89RkFMU0UsIHJlc3VsdHM9J2hpZGUnLCBldmFsPUZBTFNFfQppZighZGlyLmV4aXN0cyhmaWxlLnBhdGgob3V0cHV0X2RpciwgInJhbmRHcGxvdHMiKSkpe2Rpci5jcmVhdGUoZmlsZS5wYXRoKG91dHB1dF9kaXIsICJyYW5kR3Bsb3RzIikpfQpzZXQuc2VlZCgxMjMpCk5fc2VsIDwtIDIwCmNob3Nlbl9pZCA8LSBzYW1wbGUoMTpucm93KHJkc19vYmopLCBOX3NlbCwgcmVwbGFjZT1GQUxTRSkKCmN0c19zdWJzZXQgPC0gY3RzW2Nob3Nlbl9pZCwgXQpjcG1fc3Vic2V0IDwtIGNwbShjdHMsIGxvZz1GQUxTRSlbY2hvc2VuX2lkLCBdCmxvZ0NQTV9zdWJzZXQgPC0gY3BtKGN0cywgbG9nPVRSVUUpW2Nob3Nlbl9pZCwgXQpkYXRhX2xzdCA8LSBsaXN0KENvdW50cz1jdHNfc3Vic2V0LCBDUE09Y3BtX3N1YnNldCwgbG9nMkNQTT1sb2dDUE1fc3Vic2V0KQoKdm9pZCA8LSBtYXBwbHkoZnVuY3Rpb24oZGF0LCBkYXRfbmFtZSwgbWV0YV9pbmZvKXsKICBmb3IoaSBpbiAxOm5yb3coZGF0KSl7CiAgICAjIHByZXBhcmUgZGF0YSBmcmFtZQogICAgY3Vycl9kZiA8LSBkYXRhLmZyYW1lKHNhbXBsZXM9Y29sbmFtZXMoZGF0KSwgdmFsdWU9ZGF0W2ksIF0pCiAgICBjdXJyX2RmIDwtIG1lcmdlKHg9Y3Vycl9kZiwgeT1tZXRhX2luZm8sIGJ5Lng9InNhbXBsZXMiLCBieS55PSJzYW1wbGUiKQogICAgCiAgICAjIHNjYXR0ZXIgcGxvdCBmb3IgaS10aCBnZW5lCiAgICBwX3NjYXR0ZXIgPC0gZ2dwbG90KGN1cnJfZGYsIGFlcyh4PXNhbXBsZXMsIHk9dmFsdWUsIGNvbG9yPWJhdGNoLCBzaGFwZT1jb25kKSkgKwogICAgICBnZW9tX3BvaW50KCkgKwogICAgICBsYWJzKHg9IlNhbXBsZXMiLCB5PWRhdF9uYW1lLCB0aXRsZT1yb3duYW1lcyhkYXQpW2ldKSArCiAgICAgIHRoZW1lKGF4aXMudGV4dC54PWVsZW1lbnRfYmxhbmsoKSkKICAgIAogICAgIyB2aW9saW4gcGxvdCBmb3IgaS10aCBnZW5lCiAgICBwX3Zpb2xpbiA8LSBnZ3Bsb3QoY3Vycl9kZiwgYWVzKDAsIHZhbHVlKSkgKyAKICAgICAgZ2VvbV92aW9saW4oKSArCiAgICAgIGdlb21fYm94cGxvdCh3aWR0aD0wLjIpICsKICAgICAgY29vcmRfZmxpcCgpICsKICAgICAgZ2VvbV90ZXh0KGFlcyhsYWJlbD1hcy5pbnRlZ2VyKG1lZGlhbihjdXJyX2RmJHZhbHVlKSksIHg9MC4xMiwgeT1tZWRpYW4oY3Vycl9kZiR2YWx1ZSkpKSArCiAgICAgIGxhYnMoeT1kYXRfbmFtZSwgdGl0bGU9c3ByaW50ZigiQWxsIHNhbXBsZXMsICVzIiwgcm93bmFtZXMoZGF0KVtpXSkpICsKICAgICAgdGhlbWUoYXhpcy50aXRsZS55PWVsZW1lbnRfYmxhbmsoKSkKICAgIAogICAgIyB2aW9saW4gcGxvdCBncm91cCBieSBiYXRjaAogICAgbWVkaWFuc19iYXRjaCA8LSBhZ2dyZWdhdGUodmFsdWUgfiBiYXRjaCwgZGF0YT1jdXJyX2RmLCBGVU49bWVkaWFuKQogICAgcF92aW9saW5fYmF0Y2ggPC0gZ2dwbG90KGN1cnJfZGYsIGFlcyh4PWJhdGNoLCB5PXZhbHVlLCBjb2xvcj1iYXRjaCkpICsgCiAgICAgIGdlb21fdmlvbGluKCkgKwogICAgICBnZW9tX2JveHBsb3Qod2lkdGg9MC4yKSArCiAgICAgIGNvb3JkX2ZsaXAoKSArCiAgICAgIHNjYWxlX2NvbG9yX21hbnVhbCh2YWx1ZXM9YygnI0U2OUYwMCcsICcjNTZCNEU5JykpICsKICAgICAgZ2VvbV90ZXh0KGRhdGE9bWVkaWFuc19iYXRjaCwgCiAgICAgICAgICAgICAgICBhZXMobGFiZWw9cm91bmQobWVkaWFuc19iYXRjaCR2YWx1ZSwyKSwgeD1hcy5udW1lcmljKGFzLmNoYXJhY3RlcihtZWRpYW5zX2JhdGNoJGJhdGNoKSkrMC4xMiwKICAgICAgICAgICAgICAgICAgICB5PWFzLm51bWVyaWMoYXMuY2hhcmFjdGVyKG1lZGlhbnNfYmF0Y2gkdmFsdWUpKSkpICsKICAgICAgbGFicyh5PWRhdF9uYW1lLCB0aXRsZT1zcHJpbnRmKCJJbiBiYXRjaGVzLCAlcyIsIHJvd25hbWVzKGRhdClbaV0pKSArCiAgICAgIHRoZW1lKGF4aXMudGl0bGUueT1lbGVtZW50X2JsYW5rKCkpCiAgICAKICAgICMgdmlvbGluIHBsb3QgZ3JvdXAgYnkgY29uZGl0aW9uCiAgICBtZWRpYW5zX2NvbmQgPC0gYWdncmVnYXRlKHZhbHVlIH4gY29uZCwgZGF0YT1jdXJyX2RmLCBGVU49bWVkaWFuKQogICAgcF92aW9saW5fY29uZCA8LSBnZ3Bsb3QoY3Vycl9kZiwgYWVzKHg9Y29uZCwgeT12YWx1ZSwgY29sb3I9Y29uZCkpICsgCiAgICAgIGdlb21fdmlvbGluKCkgKwogICAgICBnZW9tX2JveHBsb3Qod2lkdGg9MC4yKSArCiAgICAgIGNvb3JkX2ZsaXAoKSArCiAgICAgIGdlb21fdGV4dChkYXRhPW1lZGlhbnNfY29uZCwKICAgICAgICAgICAgICAgIGFlcyhsYWJlbD1yb3VuZChtZWRpYW5zX2NvbmQkdmFsdWUsMiksIHg9YXMubnVtZXJpYyhhcy5jaGFyYWN0ZXIobWVkaWFuc19jb25kJGNvbmQpKSsxLjEyLCAKICAgICAgICAgICAgICAgICAgICB5PWFzLm51bWVyaWMoYXMuY2hhcmFjdGVyKG1lZGlhbnNfY29uZCR2YWx1ZSkpKSkgKwogICAgICBsYWJzKHk9ZGF0X25hbWUsIHRpdGxlPXNwcmludGYoIkluIGNvbmRpdGlvbiBncm91cHMsICVzIiwgcm93bmFtZXMoZGF0KVtpXSkpICsKICAgICAgdGhlbWUoYXhpcy50aXRsZS55PWVsZW1lbnRfYmxhbmsoKSkKICAgIAogICAgIyBvdXRwdXQgcGxvdAogICAgcG5nKHNwcmludGYoIiVzLyVzX2dlbmUlcy5wbmciLCBmaWxlLnBhdGgob3V0cHV0X2RpciwgInJhbmRHcGxvdHMiKSwgZGF0X25hbWUsIGkpLAogICAgICAgIHdpZHRoPTEwLCBoZWlnaHQ9OCwgdW5pdHM9ImluIiwgcmVzPTMwMCkKICAgIGdyaWQuYXJyYW5nZShwX3NjYXR0ZXIsIHBfdmlvbGluLCBwX3Zpb2xpbl9iYXRjaCwgcF92aW9saW5fY29uZCwgbnJvdz0yLCBuY29sPTIpCiAgICBkZXYub2ZmKCkKICB9Cn0sIGRhdD1kYXRhX2xzdCwgZGF0X25hbWU9bmFtZXMoZGF0YV9sc3QpLCBtZXRhX2luZm89bGlzdChtZXRhX2luZm8sbWV0YV9pbmZvLG1ldGFfaW5mbykpCgpybShjdHNfc3Vic2V0LCBjcG1fc3Vic2V0LCBsb2dDUE1fc3Vic2V0LCBsaWJfc2l6ZXMsIGxpYl9zaXplc19kZiwgY2hvc2VuX2lkLCBkYXRhX2xzdCwgdm9pZCwgTl9zZWwpCmBgYAoKCiMjIyBGb2xkIGNoYW5nZXMgaW4gbWVhbiB7LnRhYnNldH0KCldlIHVzZSBlZGdlUiB0byBwZXJmb3JtIGRpZmZlcmVudGlhbCBleHByZXNzaW9uIGFuYWx5c2lzLCBhbmQgY2FsY3VsYXRlIChsb2ctKSBmb2xkIGNoYW5nZXMgb2YgYWxsIGdlbmVzIGJldHdlZW4gY29uZGl0aW9uIGdyb3VwcyBhbmQgYmF0Y2hlcy4KCiMjIyMgQ2hhbmdlIFdSVCBjb25kaXRpb24KClRvIHJ1bGUgb3V0IHRoZSBpbXBhY3Qgb2YgYmF0Y2ggZWZmZWN0LCB3ZSBsaW1pdCBvdXIgREUgYW5hbHlzaXMgd2l0aCByZWdhcmQgdG8gYmlvbG9naWNhbCBjb25kaXRpb24gaW4gb25lIG9mIHRoZSBiYXRjaGVzLiBIZXJlIHdlIHNwZWNpZnkgdGhlIGJhdGNoIHRvIGJlICoqRzYqKiBkdWUgdG8gYSBsYXJnZXIgYmF0Y2ggc2l6ZSwgYW5kIGV2YWx1YXRlIERFICoqYmV0d2VlbiBwcm9ncmVzc29ycyBhbmQgbm9uLXByb2dyZXNzb3JzKiouCgpgYGB7ciwgcmVzdWx0cz0iaGlkZSJ9CiMjIyMgIERpZmZlcmVudGlhbCBnZW5lcyByZWxhdGl2ZSB0byBiaW9sb2dpY2FsIGNvbmRpdGlvbiAKIyMjIyAgKHdpdGhpbiBiYXRjaCAxIC8gYmF0Y2ggc3BlY2lmaWVkIGJ5ICd0ZXN0X2JhdGNoJykKdGVzdF9iYXRjaCA8LSAiRzYiCmNvdW50c19iYXRjaCA8LSBhc3NheShyZHNfb2JqLCJjb3VudHMiKVssIGJhdGNoPT10ZXN0X2JhdGNoXQpjb25kX2JhdGNoIDwtIGFzLmZhY3Rvcihhcy5jaGFyYWN0ZXIoZ3JvdXBbYmF0Y2g9PXRlc3RfYmF0Y2hdKSkKCnkgPC0gREdFTGlzdChjb3VudHM9Y291bnRzX2JhdGNoLCBncm91cD1hcy5mYWN0b3IoY29uZF9iYXRjaCkpCnkgPC0gY2FsY05vcm1GYWN0b3JzKHksIG1ldGhvZD0iVE1NIikKZGVzaWduIDwtIG1vZGVsLm1hdHJpeCh+YXMuZmFjdG9yKGNvbmRfYmF0Y2gpKQp5IDwtIGVzdGltYXRlRGlzcCh5LCBkZXNpZ24pCmZpdCA8LSBnbG1RTEZpdCh5LCBkZXNpZ24pCnFsZiA8LSBnbG1RTEZUZXN0KGZpdCwgY29lZj0yKQpkZV9yZXMgPC0gdG9wVGFncyhxbGYsIG49bnJvdyhyZHNfb2JqKSkKIAp1cF9nZW5lcyA8LSByb3duYW1lcyhkZV9yZXMpW2RlX3JlcyR0YWJsZSRsb2dGQyA+PSAwXSAgIyBhbGwgdXAtcmVndWxhdGVkIGdlbmVzIChkZXNjZW5kaW5nIG9yZGVyIGluIHRlcm1zIG9mIHAgdmFsdWUpCmhlYWRfdXBfZ2VuZXMgPC0gaGVhZCh1cF9nZW5lcywgbj01MCkgICMgdG9wLTUwIHNpZ25pZmljYW50IHVwLXJlZ3VsYXRlZCBnZW5lcwp0YWlsX3VwX2dlbmVzIDwtIHRhaWwodXBfZ2VuZXMsIG49NTApICAjIDUwIGxlYXN0IHNpZ25pZmljYW50IHVwLXJlZ3VsYXRlZCBnZW5lcwoKY29uZF91cF9pbmRzIDwtIHVwX2dlbmVzCgpkb3duX2dlbmVzIDwtIHJvd25hbWVzKGRlX3JlcylbZGVfcmVzJHRhYmxlJGxvZ0ZDIDwgMF0gICMgYWxsIGRvd24tcmVndWxhdGVkIGdlbmVzCmhlYWRfZG93bl9nZW5lcyA8LSBoZWFkKGRvd25fZ2VuZXMsIG49NTApICAjIHRvcC01MCBzaWduaWZpY2FudCBkb3duLXJlZ3VsYXRlZCBnZW5lcwp0YWlsX2Rvd25fZ2VuZXMgPC0gdGFpbChkb3duX2dlbmVzLCBuPTUwKSAgIyA1MCBsZWFzdCBzaWduaWZpY2FudCBkb3duLXJlZ3VsYXRlZCBnZW5lcwoKY29uZF9kb3duX2luZHMgPC0gZG93bl9nZW5lcwpgYGAKCmBgYHtyLCBlY2hvPUZBTFNFLCBtZXNzYWdlPUZBTFNFfQojIGNoYW5nZXMgaW4gdGVybXMgb2YgbWVhbgpjYXQoIiMjIyMjIyAgQ2hhbmdlcyBpbiB0ZXJtcyBvZiBhdmVyYWdlIGdlbmUgY291bnRzICAjIyMjIyNcbiIpCm1lYW5fY3RzX21hdCA8LSBtYXRyaXgoTkEsIG5yb3c9MiwgbmNvbD0zLCAKICAgICAgICAgICAgICAgICAgICAgICBkaW1uYW1lcz1saXN0KGMoIk5vbi1wcm9ncmVzc29yIiwgIlByb2dyZXNzb3IiKSwgYygidG9wNTAgdXAiLCAidG9wNTAgZG93biIsICIxMDAgbGVhc3QgREUiKSkpCm1lYW5fY3RzX21hdFsiTm9uLXByb2dyZXNzb3IiLCAidG9wNTAgdXAiXSA8LSBtZWFuKGNvdW50c19iYXRjaFtoZWFkX3VwX2dlbmVzLCBjb25kX2JhdGNoPT0iTm9uLXByb2dyZXNzb3IiXSkKbWVhbl9jdHNfbWF0WyJQcm9ncmVzc29yIiwgInRvcDUwIHVwIl0gPC0gbWVhbihjb3VudHNfYmF0Y2hbaGVhZF91cF9nZW5lcywgY29uZF9iYXRjaD09IlByb2dyZXNzb3IiXSkKbWVhbl9jdHNfbWF0WyJOb24tcHJvZ3Jlc3NvciIsICJ0b3A1MCBkb3duIl0gPC0gbWVhbihjb3VudHNfYmF0Y2hbaGVhZF9kb3duX2dlbmVzLCBjb25kX2JhdGNoPT0iTm9uLXByb2dyZXNzb3IiXSkKbWVhbl9jdHNfbWF0WyJQcm9ncmVzc29yIiwgInRvcDUwIGRvd24iXSA8LSBtZWFuKGNvdW50c19iYXRjaFtoZWFkX2Rvd25fZ2VuZXMsIGNvbmRfYmF0Y2g9PSJQcm9ncmVzc29yIl0pCm1lYW5fY3RzX21hdFsiTm9uLXByb2dyZXNzb3IiLCAiMTAwIGxlYXN0IERFIl0gPC0gbWVhbihjb3VudHNfYmF0Y2hbYyh0YWlsX3VwX2dlbmVzLCB0YWlsX2Rvd25fZ2VuZXMpLCBjb25kX2JhdGNoPT0iTm9uLXByb2dyZXNzb3IiXSkKbWVhbl9jdHNfbWF0WyJQcm9ncmVzc29yIiwgIjEwMCBsZWFzdCBERSJdIDwtIG1lYW4oY291bnRzX2JhdGNoW2ModGFpbF91cF9nZW5lcywgdGFpbF9kb3duX2dlbmVzKSwgY29uZF9iYXRjaD09IlByb2dyZXNzb3IiXSkKcHJpbnQocm91bmQobWVhbl9jdHNfbWF0LDEpKQoKIyBjaGFuZ2VzIGluIHRlcm1zIG9mIChsb2cpIGZvbGQgY2hhbmdlCmNhdCgiXG4jIyMjIyMgIFJhbmdlIG9mIGZvbGQgY2hhbmdlIGFjcm9zcyBiaW9sb2dpY2FsIGNvbmRpdGlvbnMgICMjIyMjI1xuIikKRkNfbWF0IDwtIG1hdHJpeChOQSwgbnJvdz00LCBuY29sPTMsIAogICAgICAgICAgICAgICAgIGRpbW5hbWVzPWxpc3QoYygibWluIEZDIiwgIm1lZGlhbiBGQyIsICJtZWFuIEZDIiwgIm1heCBGQyIpLCAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGMoInRvcDUwIHVwIiwgInRvcDUwIGRvd24iLCAiMTAwIGxlYXN0IERFIikpKQpGQ19tYXRbLCAidG9wNTAgdXAiXSA8LSBzYXBwbHkoYyhtaW4sIG1lZGlhbiwgbWVhbiwgbWF4KSwgZnVuY3Rpb24oZmYpe2ZmKGV4cChkZV9yZXMkdGFibGVbaGVhZF91cF9nZW5lcywgImxvZ0ZDIl0pKX0pCkZDX21hdFssICJ0b3A1MCBkb3duIl0gPC0gc2FwcGx5KGMobWluLCBtZWRpYW4sIG1lYW4sIG1heCksIGZ1bmN0aW9uKGZmKXtmZihleHAoZGVfcmVzJHRhYmxlW2hlYWRfZG93bl9nZW5lcywgImxvZ0ZDIl0pKX0pCkZDX21hdFssICIxMDAgbGVhc3QgREUiXSA8LSBzYXBwbHkoYyhtaW4sIG1lZGlhbiwgbWVhbiwgbWF4KSwgZnVuY3Rpb24oZmYpewogIGZmKGV4cChkZV9yZXMkdGFibGVbYyh0YWlsX3VwX2dlbmVzLCB0YWlsX2Rvd25fZ2VuZXMpLCAibG9nRkMiXSkpCn0pCnByaW50KHJvdW5kKEZDX21hdCwzKSkKCmNhdCgiXG4jIyMjIyMgIFJhbmdlIG9mIExvZyhmb2xkIGNoYW5nZSkgYWNyb3NzIGJpb2xvZ2ljYWwgY29uZGl0aW9ucyAgIyMjIyMjXG4iKQpsb2dGQ19tYXQgPC0gbG9nKEZDX21hdCkKcm93bmFtZXMobG9nRkNfbWF0KSA8LSBjKCJtaW4gbG9nRkMiLCAibWVkaWFuIGxvZ0ZDIiwgIm1lYW4gbG9nRkMiLCAibWF4IGxvZ0ZDIikKcHJpbnQocm91bmQobG9nRkNfbWF0LDMpKQoKCiMgdmlzdWFsaXplIGNoYW5nZSBpbiB0ZXJtcyBvZiAobG9nKSBmb2xkIGNoYW5nZQpsb2dGQ19kZiA8LSBkYXRhLmZyYW1lKHRvcDUwdXA9ZGVfcmVzJHRhYmxlW2hlYWRfdXBfZ2VuZXMsICJsb2dGQyJdLCB0b3A1MGRvd249ZGVfcmVzJHRhYmxlW2hlYWRfZG93bl9nZW5lcywgImxvZ0ZDIl0pCkZDX2RmIDwtIGV4cChsb2dGQ19kZikKcF9sb2dGQyA8LSBnZ3Bsb3QobWVsdChsb2dGQ19kZiksIGFlcyh4PXZhcmlhYmxlLCB5PXZhbHVlKSkgKwogIGdlb21fYm94cGxvdCgpICsKICBsYWJzKHk9ImxvZ0ZDIikgKwogIHRoZW1lKGF4aXMudGl0bGUueD1lbGVtZW50X2JsYW5rKCkpCnBfRkMgPC0gZ2dwbG90KG1lbHQoRkNfZGYpLCBhZXMoeD12YXJpYWJsZSwgeT12YWx1ZSkpICsKICBnZW9tX2JveHBsb3QoKSArCiAgbGFicyh5PSJGQyIpICsKICB0aGVtZShheGlzLnRpdGxlLng9ZWxlbWVudF9ibGFuaygpKQpncmlkLmFycmFuZ2UocF9sb2dGQywgcF9GQywgbmNvbD0yKQpgYGAKCmBgYHtyLCBlY2hvPUZBTFNFLCByZXN1bHRzPSdoaWRlJ30Kcm0oY29uZF9iYXRjaCwgY291bnRzX2JhdGNoLCB1cF9nZW5lcywgaGVhZF91cF9nZW5lcywgdGFpbF91cF9nZW5lcywgCiAgIGRvd25fZ2VuZXMsIGhlYWRfZG93bl9nZW5lcywgdGFpbF9kb3duX2dlbmVzLCB5LCBkZXNpZ24sIGZpdCwgcWxmLCBkZV9yZXMsIAogICBtZWFuX2N0c19tYXQsIEZDX21hdCwgcF9GQywgcF9sb2dGQywgRkNfZGYsIGxvZ0ZDX2RmLCBsb2dGQ19tYXQpCmBgYAoKKipDb25jbHVzaW9uczoqKgoKKyBCaW9sb2dpY2FsIGZvbGQgY2hhbmdlIGNvbXBhcmluZyBhdmVyYWdlIGNvdW50cyAqKmluIHRvcCBERSBnZW5lcyoqIGlzIGFib3V0IDEuMi0xLjguIAorIEdlbmUtd2lzZSBmb2xkIGNoYW5nZSAqKmluIHRvcCBERSBnZW5lcyoqIGhhcyBhIHdpZGUgcmFuZ2UgKG1lZGlhbiA0LCBtZWFuIDIxKS4KCgojIyMjIENoYW5nZSBXUlQgYmF0Y2gKCldlIGFyZSBhbHNvIGludGVyZXN0ZWQgdG8gc2VlIGhvdyB0aGUgYXZlcmFnZSAobWVhbikgZ2VuZSBjb3VudHMgY2hhbmdlIGFjcm9zcyBiYXRjaGVzIChpLmUuICoqZGVncmVlIG9mIG1lYW4gYmF0Y2ggZWZmZWN0KiopLiAKClRvIGV4cGxvcmUgdGhpcyBtZWFuIGJhdGNoIGVmZmVjdCwgd2UgKipmaXJzdCBwZXJmb3JtIERFIHdpdGggcmVnYXJkIHRvIHRoZSBiYXRjaCB2YXJpYWJsZSoqLiBUbyBydWxlIG91dCB0aGUgaW1wYWN0IG9mIGJpb2xvZ2ljYWwgY29uZGl0aW9uLCB3ZSBwZXJmb3JtIHRoaXMgYW5hbHlzaXMgd2l0aGluICoqTm9uLXByb2dyZXNzb3JzKiogb25seSwgYW5kIGNvbXBhcmUgKipBZnJpY2EgJiBHNiBzdHVkaWVzKiouIE5vdGUgdGhhdCB0aGlzIERFIGlzIG5vdCB0cnVlIERFIC0gaXQncyB0ZXN0aW5nIGlmIHRoZXJlIGlzIGEgc2lnbmlmaWNhbnQgbWVhbiBkaWZmZXJlbmNlIGJldHdlZW4gdHdvIGJhdGNoZXMuIAoKYGBge3IsIHJlc3VsdHM9ImhpZGUifQojIyMjICBEaWZmZXJlbnRpYWwgZ2VuZXMgcmVsYXRpdmUgdG8gYmF0Y2ggCiMjIyMgICh3aXRoaW4gY29uZGl0aW9uIDAgLyBjb25kaXRpb24gc3BlY2lmaWVkIGJ5ICd0ZXN0X2NvbmQnKQpyZHNfc3Vic2V0IDwtIHJkc19vYmpbLCByZHNfb2JqJERhdGFzZXQgJWluJSBjKCJBZnJpY2EiLCAiRzYiKV0KdGVzdF9jb25kIDwtICJOb24tcHJvZ3Jlc3NvciIKY291bnRzX2NvbmQgPC0gYXNzYXkocmRzX3N1YnNldCwgImNvdW50cyIpWywgcmRzX3N1YnNldCRMYWJlbD09dGVzdF9jb25kXQpiYXRjaF9jb25kIDwtIGFzLmZhY3Rvcihhcy5jaGFyYWN0ZXIocmRzX3N1YnNldCRTZXF1ZW5jaW5nQmF0Y2hbcmRzX3N1YnNldCRMYWJlbD09dGVzdF9jb25kXSkpCgp5IDwtIERHRUxpc3QoY291bnRzPWNvdW50c19jb25kLCBncm91cD1hcy5mYWN0b3IoYmF0Y2hfY29uZCkpCnkgPC0gY2FsY05vcm1GYWN0b3JzKHksIG1ldGhvZD0iVE1NIikKZGVzaWduIDwtIG1vZGVsLm1hdHJpeCh+YXMuZmFjdG9yKGJhdGNoX2NvbmQpKQp5IDwtIGVzdGltYXRlRGlzcCh5LCBkZXNpZ24pCmZpdCA8LSBnbG1RTEZpdCh5LCBkZXNpZ24pCnFsZiA8LSBnbG1RTEZUZXN0KGZpdCwgY29lZj0yKQpkZV9yZXMgPC0gdG9wVGFncyhxbGYsIG49bnJvdyhyZHNfc3Vic2V0KSkKCnVwX2dlbmVzIDwtIHJvd25hbWVzKGRlX3JlcylbZGVfcmVzJHRhYmxlJGxvZ0ZDID49IDBdICAjIGFsbCB1cC1yZWd1bGF0ZWQgZ2VuZXMKaGVhZF91cF9nZW5lcyA8LSBoZWFkKHVwX2dlbmVzLCBuPTUwKSAgIyB0b3AtNTAgdXAtcmVndWxhdGVkIGdlbmVzCnRhaWxfdXBfZ2VuZXMgPC0gdGFpbCh1cF9nZW5lcywgbj01MCkgICMgNTAgbGVhc3QgdXAtcmVndWxhdGVkIGdlbmVzCgpiYXRjaF91cF9pbmRzIDwtIHVwX2dlbmVzCgpkb3duX2dlbmVzIDwtIHJvd25hbWVzKGRlX3JlcylbZGVfcmVzJHRhYmxlJGxvZ0ZDIDwgMF0gICMgYWxsIGRvd24tcmVndWxhdGVkIGdlbmVzCmhlYWRfZG93bl9nZW5lcyA8LSBoZWFkKGRvd25fZ2VuZXMsIG49NTApICAjIHRvcC01MCBkb3duLXJlZ3VsYXRlZCBnZW5lcwp0YWlsX2Rvd25fZ2VuZXMgPC0gdGFpbChkb3duX2dlbmVzLCBuPTUwKSAgIyA1MCBsZWFzdCBkb3duLXJlZ3VsYXRlZCBnZW5lcwoKYmF0Y2hfZG93bl9pbmRzIDwtIGRvd25fZ2VuZXMKYGBgCgpgYGB7ciwgZWNobz1GQUxTRX0KIyBjaGFuZ2VzIGluIHRlcm1zIG9mIG1lYW4KY2F0KCIjIyMjIyMgIEJhdGNoIGRpZmZlcmVuY2VzIGluIHRlcm1zIG9mIG1lYW4gZ2VuZSBjb3VudHMgICMjIyMjI1xuIikKbWVhbl9jdHNfbWF0IDwtIG1hdHJpeChOQSwgbnJvdz0yLCBuY29sPTMsIAogICAgICAgICAgICAgICAgICAgICAgIGRpbW5hbWVzPWxpc3QoYygiQWZyaWNhIiwgIkc2IiksIGMoInRvcDUwIHVwIiwgInRvcDUwIGRvd24iLCAiMTAwIGxlYXN0IGNoYW5nZWQiKSkpCm1lYW5fY3RzX21hdFsiQWZyaWNhIiwgInRvcDUwIHVwIl0gPC0gbWVhbihjb3VudHNfY29uZFtoZWFkX3VwX2dlbmVzLCBiYXRjaF9jb25kPT0iQWZyaWNhIl0pCm1lYW5fY3RzX21hdFsiRzYiLCAidG9wNTAgdXAiXSA8LSBtZWFuKGNvdW50c19jb25kW2hlYWRfdXBfZ2VuZXMsIGJhdGNoX2NvbmQ9PSJHNiJdKQptZWFuX2N0c19tYXRbIkFmcmljYSIsICJ0b3A1MCBkb3duIl0gPC0gbWVhbihjb3VudHNfY29uZFtoZWFkX2Rvd25fZ2VuZXMsIGJhdGNoX2NvbmQ9PSJBZnJpY2EiXSkKbWVhbl9jdHNfbWF0WyJHNiIsICJ0b3A1MCBkb3duIl0gPC0gbWVhbihjb3VudHNfY29uZFtoZWFkX2Rvd25fZ2VuZXMsIGJhdGNoX2NvbmQ9PSJHNiJdKQptZWFuX2N0c19tYXRbIkFmcmljYSIsICIxMDAgbGVhc3QgY2hhbmdlZCJdIDwtIG1lYW4oY291bnRzX2NvbmRbYyh0YWlsX3VwX2dlbmVzLCB0YWlsX2Rvd25fZ2VuZXMpLCBiYXRjaF9jb25kPT0iQWZyaWNhIl0pCm1lYW5fY3RzX21hdFsiRzYiLCAiMTAwIGxlYXN0IGNoYW5nZWQiXSA8LSBtZWFuKGNvdW50c19jb25kW2ModGFpbF91cF9nZW5lcywgdGFpbF9kb3duX2dlbmVzKSwgYmF0Y2hfY29uZD09Ikc2Il0pCnByaW50KHJvdW5kKG1lYW5fY3RzX21hdCwyKSkKCiMgY2hhbmdlcyBpbiB0ZXJtcyBvZiBmb2xkIGNoYW5nZQpjYXQoIlxuIyMjIyMjICBSYW5nZSBvZiBmb2xkIGNoYW5nZSBiZXR3ZWVuIGJhdGNoZXMgICMjIyMjI1xuIikKY2F0KCItIEFsbCBnZW5lcyAtIEZDOlxuIikKY2F0KHJvdW5kKHJhbmdlKGV4cChkZV9yZXMkdGFibGUkbG9nRkMpKSwgMykpIAoKY2F0KCJcblxuLSBBbGwgZ2VuZXMgLSBsb2coRkMpOlxuIikKY2F0KHJvdW5kKHJhbmdlKGRlX3JlcyR0YWJsZSRsb2dGQyksIDMpKSAKCmNhdCgiXG5cbi0gVG9wIGdlbmVzIC0gRkM6XG4iKQpGQ19tYXQgPC0gbWF0cml4KE5BLCBucm93PTQsIG5jb2w9MywgCiAgICAgICAgICAgICAgICAgZGltbmFtZXM9bGlzdChjKCJtaW4gRkMiLCAibWVkaWFuIEZDIiwgIm1lYW4gRkMiLCAibWF4IEZDIiksIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgYygidG9wNTAgdXAiLCAidG9wNTAgZG93biIsICIxMDAgbGVhc3QgREUiKSkpCkZDX21hdFssICJ0b3A1MCB1cCJdIDwtIHNhcHBseShjKG1pbiwgbWVkaWFuLCBtZWFuLCBtYXgpLCBmdW5jdGlvbihmZil7ZmYoZXhwKGRlX3JlcyR0YWJsZVtoZWFkX3VwX2dlbmVzLCAibG9nRkMiXSkpfSkKRkNfbWF0WywgInRvcDUwIGRvd24iXSA8LSBzYXBwbHkoYyhtaW4sIG1lZGlhbiwgbWVhbiwgbWF4KSwgZnVuY3Rpb24oZmYpe2ZmKGV4cChkZV9yZXMkdGFibGVbaGVhZF9kb3duX2dlbmVzLCAibG9nRkMiXSkpfSkKRkNfbWF0WywgIjEwMCBsZWFzdCBERSJdIDwtIHNhcHBseShjKG1pbiwgbWVkaWFuLCBtZWFuLCBtYXgpLCBmdW5jdGlvbihmZil7CiAgZmYoZXhwKGRlX3JlcyR0YWJsZVtjKHRhaWxfdXBfZ2VuZXMsIHRhaWxfZG93bl9nZW5lcyksICJsb2dGQyJdKSkKfSkKcHJpbnQocm91bmQoRkNfbWF0LDMpKQoKY2F0KCJcbi0gVG9wIGdlbmVzIC0gbG9nKEZDKTpcbiIpCmxvZ0ZDX21hdCA8LSBsb2coRkNfbWF0KQpyb3duYW1lcyhsb2dGQ19tYXQpIDwtIGMoIm1pbiBsb2dGQyIsICJtZWRpYW4gbG9nRkMiLCAibWVhbiBsb2dGQyIsICJtYXggbG9nRkMiKQpwcmludChyb3VuZChsb2dGQ19tYXQsMykpCgpgYGAKCmBgYHtyLCBlY2hvPUZBTFNFLCByZXN1bHRzPSdoaWRlJ30Kcm0oYmF0Y2hfY29uZCwgY291bnRzX2NvbmQsIHVwX2dlbmVzLCBoZWFkX3VwX2dlbmVzLCB0YWlsX3VwX2dlbmVzLCAKICAgZG93bl9nZW5lcywgaGVhZF9kb3duX2dlbmVzLCB0YWlsX2Rvd25fZ2VuZXMsIHksIGRlc2lnbiwgZml0LCBxbGYsIGRlX3JlcywgCiAgIG1lYW5fY3RzX21hdCwgRkNfbWF0LCBsb2dGQ19tYXQpCmBgYAoKKipDb25jbHVzaW9uczoqKgoKKyBNZWFuIGJhdGNoIGVmZmVjdCBmb2xkIGNoYW5nZSBjb21wYXJpbmcgYXZlcmFnZSBjb3VudHMgKippbiB0b3AgZ2VuZXMqKiByYW5nZXMgZnJvbSAxLjE4LTMuNTYuICoqUmVtZW1iZXIgdGhhdCB0aGVzZSBhcmUgZ2VuZXMgbW9zdCBzaWduaWZpY2FudGx5IGRpZmZlcmVudCBhY3Jvc3MgYmF0Y2gqKi4KKyBHZW5lLXdpc2UgbWVhbiBiYXRjaCBlZmZlY3QgZm9sZCBjaGFuZ2UgKippbiB0b3AgZ2VuZXMqKiBoYXMgYSB3aWRlIHJhbmdlIChtZWFuIDQuNCwgbWVkaWFuIDUyLjYpLgoKCiMjIyBCYXRjaCBtZWFuCgoqKk1lZGlhbiAob2YgYWxsIGdlbmVzKSoqIGdlbmUtd2lzZSBtZWFuOiAKCmBgYHtyLCBlY2hvPUZBTFNFfQptZWFuX3RiIDwtIG1hdHJpeChOQSwgbnJvdz0yLCBuY29sPTMsIAogICAgICAgICAgICAgICAgIGRpbW5hbWVzPWxpc3QoYygiTm9uLXByb2dyZXNzb3IiLCAiUHJvZ3Jlc3NvciIpLCBjKCJBZnJpY2EiLCAiRzYiLCAiQnJhemlsMSIpKSkKbWVhbl90YlsiTm9uLXByb2dyZXNzb3IiLCAiQWZyaWNhIl0gPC0gbWVkaWFuKHJvd01lYW5zKGN0c1ssIGJhdGNoPT0iQWZyaWNhIiZncm91cD09Ik5vbi1wcm9ncmVzc29yIl0pKQptZWFuX3RiWyJQcm9ncmVzc29yIiwgIkFmcmljYSJdIDwtIG1lZGlhbihyb3dNZWFucyhjdHNbLCBiYXRjaD09IkFmcmljYSImZ3JvdXA9PSJQcm9ncmVzc29yIl0pKQptZWFuX3RiWyJOb24tcHJvZ3Jlc3NvciIsICJHNiJdIDwtIG1lZGlhbihyb3dNZWFucyhjdHNbLCBiYXRjaD09Ikc2IiZncm91cD09Ik5vbi1wcm9ncmVzc29yIl0pKQptZWFuX3RiWyJQcm9ncmVzc29yIiwgIkc2Il0gPC0gbWVkaWFuKHJvd01lYW5zKGN0c1ssIGJhdGNoPT0iRzYiJmdyb3VwPT0iUHJvZ3Jlc3NvciJdKSkKbWVhbl90YlsiTm9uLXByb2dyZXNzb3IiLCAiQnJhemlsMSJdIDwtIG1lZGlhbihyb3dNZWFucyhjdHNbLCBiYXRjaD09IkJyYXppbF8xIiZncm91cD09Ik5vbi1wcm9ncmVzc29yIl0pKQptZWFuX3RiWyJQcm9ncmVzc29yIiwgIkJyYXppbDEiXSA8LSBtZWRpYW4ocm93TWVhbnMoY3RzWywgYmF0Y2g9PSJCcmF6aWxfMSImZ3JvdXA9PSJQcm9ncmVzc29yIl0pKQpwcmludChyb3VuZChtZWFuX3RiLCAyKSkKYGBgCgpTY2FsZWQgYnkgdGhhdCBvZiBBZnJpY2E6CgpgYGB7ciwgZWNobz1GQUxTRX0KbWVhbl90Yl9zY2FsZWQgPC0gYXBwbHkobWVhbl90YiwgMiwgZnVuY3Rpb24oeCl7eC9tZWFuX3RiWywiQWZyaWNhIl19KQpwcmludChyb3VuZChtZWFuX3RiX3NjYWxlZCwgMikpCmBgYAoKCiMjIyBCYXRjaCBkaXNwZXJzaW9uCgpBc2lkZSBmcm9tIGF2ZXJhZ2UgZ2VuZSBjb3VudHMsIHdlIGFyZSBpbnRlcmVzdGVkIGluIGNvbXBhcmluZyBkaXNwZXJzaW9ucyBpbiB0aGUgYmF0Y2hlcy4gKipEaWZmZXJlbmNlIGluIHRoZSBkaXNwZXJzaW9ucyBhY3Jvc3MgYmF0Y2hlcyBzdWdnZXN0cyB2YXJpYW5jZSBiYXRjaCBlZmZlY3Qgbm90IGFjY291bnRlZCBmb3IgYnkgUG9pc3NvbiBtb2RlbCoqLiBXZSB2aXN1YWxpemUgdGhlIGdlbmUtd2lzZSBkaXNwZXJzaW9uIGVzdGltYXRlcyBmcm9tIGVkZ2VSOgoKYGBge3IsIGVjaG89RkFMU0V9CiMjIyMgIERpc3BlcnNpb24gZGlmZmVyZW5jZXMgYWNyb3NzIGJhdGNoZXMgCnlfYmF0Y2gxIDwtIERHRUxpc3QoY291bnRzPWFzc2F5KHJkc19vYmosImNvdW50cyIpWywgYmF0Y2g9PSJBZnJpY2EiXSwgZ3JvdXA9YXMuZmFjdG9yKGFzLmNoYXJhY3Rlcihncm91cFtiYXRjaD09IkFmcmljYSJdKSkpCnlfYmF0Y2gxIDwtIGNhbGNOb3JtRmFjdG9ycyh5X2JhdGNoMSwgbWV0aG9kPSJUTU0iKQpkZXNpZ25fYmF0Y2gxIDwtIG1vZGVsLm1hdHJpeCh+YXMuZmFjdG9yKGFzLmNoYXJhY3Rlcihncm91cFtiYXRjaD09IkFmcmljYSJdKSkpCnlfYmF0Y2gxIDwtIGVzdGltYXRlRGlzcCh5X2JhdGNoMSwgZGVzaWduX2JhdGNoMSkKCnlfYmF0Y2gyIDwtIERHRUxpc3QoY291bnRzPWFzc2F5KHJkc19vYmosImNvdW50cyIpWywgYmF0Y2g9PSJHNiJdLCBncm91cD1hcy5mYWN0b3IoYXMuY2hhcmFjdGVyKGdyb3VwW2JhdGNoPT0iRzYiXSkpKQp5X2JhdGNoMiA8LSBjYWxjTm9ybUZhY3RvcnMoeV9iYXRjaDIsIG1ldGhvZD0iVE1NIikKZGVzaWduX2JhdGNoMiA8LSBtb2RlbC5tYXRyaXgofmFzLmZhY3Rvcihhcy5jaGFyYWN0ZXIoZ3JvdXBbYmF0Y2g9PSJHNiJdKSkpCnlfYmF0Y2gyIDwtIGVzdGltYXRlRGlzcCh5X2JhdGNoMiwgZGVzaWduX2JhdGNoMikKCnlfYmF0Y2gzIDwtIERHRUxpc3QoY291bnRzPWFzc2F5KHJkc19vYmosImNvdW50cyIpWywgYmF0Y2g9PSJJbmRpYSJdLCBncm91cD1hcy5mYWN0b3IoYXMuY2hhcmFjdGVyKGdyb3VwW2JhdGNoPT0iSW5kaWEiXSkpKQp5X2JhdGNoMyA8LSBjYWxjTm9ybUZhY3RvcnMoeV9iYXRjaDMsIG1ldGhvZD0iVE1NIikKZGVzaWduX2JhdGNoMyA8LSBtb2RlbC5tYXRyaXgofmFzLmZhY3Rvcihhcy5jaGFyYWN0ZXIoZ3JvdXBbYmF0Y2g9PSJJbmRpYSJdKSkpCnlfYmF0Y2gzIDwtIGVzdGltYXRlRGlzcCh5X2JhdGNoMywgZGVzaWduX2JhdGNoMykKCnlfYmF0Y2g0IDwtIERHRUxpc3QoY291bnRzPWFzc2F5KHJkc19vYmosImNvdW50cyIpWywgYmF0Y2g9PSJCcmF6aWxfMSJdLCBncm91cD1hcy5mYWN0b3IoYXMuY2hhcmFjdGVyKGdyb3VwW2JhdGNoPT0iQnJhemlsXzEiXSkpKQp5X2JhdGNoNCA8LSBjYWxjTm9ybUZhY3RvcnMoeV9iYXRjaDQsIG1ldGhvZD0iVE1NIikKZGVzaWduX2JhdGNoNCA8LSBtb2RlbC5tYXRyaXgofmFzLmZhY3Rvcihhcy5jaGFyYWN0ZXIoZ3JvdXBbYmF0Y2g9PSJCcmF6aWxfMSJdKSkpCnlfYmF0Y2g0IDwtIGVzdGltYXRlRGlzcCh5X2JhdGNoNCwgZGVzaWduX2JhdGNoNCkKCnlfYmF0Y2g1IDwtIERHRUxpc3QoY291bnRzPWFzc2F5KHJkc19vYmosImNvdW50cyIpWywgYmF0Y2g9PSJCcmF6aWxfMiJdLCBncm91cD1hcy5mYWN0b3IoYXMuY2hhcmFjdGVyKGdyb3VwW2JhdGNoPT0iQnJhemlsXzIiXSkpKQp5X2JhdGNoNSA8LSBjYWxjTm9ybUZhY3RvcnMoeV9iYXRjaDUsIG1ldGhvZD0iVE1NIikKI2Rlc2lnbl9iYXRjaDUgPC0gbW9kZWwubWF0cml4KH5hcy5mYWN0b3IoYXMuY2hhcmFjdGVyKGdyb3VwW2JhdGNoPT0iQnJhemlsXzIiXSkpKQp5X2JhdGNoNSA8LSBlc3RpbWF0ZURpc3AoeV9iYXRjaDUpCgpkaXNwX2RmIDwtIGRhdGEuZnJhbWUoQWZyaWNhPXlfYmF0Y2gxJHRhZ3dpc2UuZGlzcGVyc2lvbiwgRzY9eV9iYXRjaDIkdGFnd2lzZS5kaXNwZXJzaW9uLCAKICAgICAgICAgICAgICAgICAgICAgIEluZGlhPXlfYmF0Y2gzJHRhZ3dpc2UuZGlzcGVyc2lvbiwgQnJhemlsXzE9eV9iYXRjaDQkdGFnd2lzZS5kaXNwZXJzaW9uLAogICAgICAgICAgICAgICAgICAgICAgQnJhemlsXzI9eV9iYXRjaDUkdGFnd2lzZS5kaXNwZXJzaW9uKQoKY2F0KCIjIyMjICBTdGF0aXN0aWNzIGFib3V0IGRpc3BlcnNpb24gZXN0aW1hdGVzIGZyb20gdGhlIHR3byBiYXRjaGVzICAjIyMjXG4iKQpkaXNwX3N0YXRzIDwtIGxhcHBseShjKG1pbiwgbWVkaWFuLCBtZWFuLCBtYXgpLCBmdW5jdGlvbihmZil7YXBwbHkoZGlzcF9kZiwgMiwgZmYpfSkKZGlzcF9zdGF0cyA8LSBkby5jYWxsKHJiaW5kLCBkaXNwX3N0YXRzKQpyb3duYW1lcyhkaXNwX3N0YXRzKSA8LSBjKCJtaW4gZGlzcC4iLCAibWVkaWFuIGRpc3AuIiwgIm1lYW4gZGlzcC4iLCAibWF4IGRpc3AuIikKcHJpbnQocm91bmQoZGlzcF9zdGF0cywgNCkpCmBgYAoKYGBge3IsIGVjaG89RkFMU0UsIG1lc3NhZ2U9RkFMU0V9CmRpc3BfZGZfbWx0IDwtIG1lbHQoZGlzcF9kZikKZ2dwbG90KGRpc3BfZGZfbWx0LCBhZXMoeD12YXJpYWJsZSwgeT12YWx1ZSkpICsKICBnZW9tX3Zpb2xpbigpICsKICBsYWJzKHg9IkJhdGNoIiwgeT0iRXN0aW1hdGVkIGdlbmUtd2lzZSBkaXNwZXJzaW9uIiwgCiAgICAgICB0aXRsZT0iQ29tcGFyaXNvbiBvZiBlc3RpbWF0ZWQgZGlzcGVyc2lvbiBhY3Jvc3MgYmF0Y2hlcyIpICsKICBzdGF0X3N1bW1hcnkoZnVuLnk9bWVhbiwgY29sb3VyPSJkYXJrcmVkIiwgZ2VvbT0icG9pbnQiLCBzaGFwZT0xOCwgc2l6ZT0zKSAjKwogICNzY2FsZV95X2NvbnRpbnVvdXMobGltaXRzPWMoMCwgMSkpCmBgYAoKKipDb25jbHVzaW9uczoqKgoKKyBNZWFuIGRpc3BlcnNpb24gaW4gdGhlIEFmcmljYSAvIEJhdGNoIDEgaW4gdGhlIEJyYXppbCBzdHVkeSBpcyBhYm91dCAxMCB0aW1lcyBvZiB0aG9zZSBpbiB0aGUgSW5kaWEgc3R1ZHkuIAorIFdlIHNlZSBodWdlIG1heCBnZW5lLXdpc2UgZGlzcGVyc2lvbnMsIHBvc3NpYmx5IGNhdXNlZCBieSAwIGNvdW50cy4KCgojIyMgQmF0Y2ggdmFyaWFuY2UKCioqTWVkaWFuIChvZiBhbGwgZ2VuZXMpKiogZ2VuZS13aXNlIHZhcmlhbmNlOiAKCmBgYHtyLCBlY2hvPUZBTFNFfQp2YXJfdGIgPC0gbWF0cml4KE5BLCBucm93PTIsIG5jb2w9MywgCiAgICAgICAgICAgICAgICAgZGltbmFtZXM9bGlzdChjKCJOb24tcHJvZ3Jlc3NvciIsICJQcm9ncmVzc29yIiksIGMoIkFmcmljYSIsICJHNiIsICJCcmF6aWwxIikpKQp2YXJfdGJbIk5vbi1wcm9ncmVzc29yIiwgIkFmcmljYSJdIDwtIG1lZGlhbihyb3dWYXJzKGN0c1ssIGJhdGNoPT0iQWZyaWNhIiZncm91cD09Ik5vbi1wcm9ncmVzc29yIl0pKQp2YXJfdGJbIlByb2dyZXNzb3IiLCAiQWZyaWNhIl0gPC0gbWVkaWFuKHJvd1ZhcnMoY3RzWywgYmF0Y2g9PSJBZnJpY2EiJmdyb3VwPT0iUHJvZ3Jlc3NvciJdKSkKdmFyX3RiWyJOb24tcHJvZ3Jlc3NvciIsICJHNiJdIDwtIG1lZGlhbihyb3dWYXJzKGN0c1ssIGJhdGNoPT0iRzYiJmdyb3VwPT0iTm9uLXByb2dyZXNzb3IiXSkpCnZhcl90YlsiUHJvZ3Jlc3NvciIsICJHNiJdIDwtIG1lZGlhbihyb3dWYXJzKGN0c1ssIGJhdGNoPT0iRzYiJmdyb3VwPT0iUHJvZ3Jlc3NvciJdKSkKdmFyX3RiWyJOb24tcHJvZ3Jlc3NvciIsICJCcmF6aWwxIl0gPC0gbWVkaWFuKHJvd1ZhcnMoY3RzWywgYmF0Y2g9PSJCcmF6aWxfMSImZ3JvdXA9PSJOb24tcHJvZ3Jlc3NvciJdKSkKdmFyX3RiWyJQcm9ncmVzc29yIiwgIkJyYXppbDEiXSA8LSBtZWRpYW4ocm93VmFycyhjdHNbLCBiYXRjaD09IkJyYXppbF8xIiZncm91cD09IlByb2dyZXNzb3IiXSkpCnByaW50KHJvdW5kKHZhcl90YiwgMikpCmBgYAoKU2NhbGVkIGJ5IHRoYXQgb2YgQWZyaWNhOgoKYGBge3IsIGVjaG89RkFMU0V9CnZhcl90Yl9zY2FsZWQgPC0gYXBwbHkodmFyX3RiLCAyLCBmdW5jdGlvbih4KXt4L3Zhcl90YlssIkFmcmljYSJdfSkKcHJpbnQocm91bmQodmFyX3RiX3NjYWxlZCwgMikpCmBgYAoKCiMjIEltcGFjdCBvZiAwIGNvdW50cyBvbiBnZW5lIGRpc3RyaWJ1dGlvbnMKCldlIGhhdmUgc2VlbiBhYm92ZSB0aGF0IG92ZXIgaGFsZiBvZiBnZW5lcyBpbiB0aGUgZGF0YXNldCBjb250YWluIHNvbWUgcG9ydGlvbnMgb2YgemVyb3MuIEhhdmluZyAwIGNvdW50cyBjYW4gaGF2ZSBhIGdvb2QgaW1wYWN0IG9uIG1lYW4gYW5kIGRpc3BlcnNpb24gZXN0aW1hdGlvbi4gV2UgZXZhbHVhdGUgc3VjaCBpbXBhY3QgaW4gdGhpcyBzZWN0aW9uLCBhbmQgc2VlIGhvdyBOQiBkaXN0cmlidXRpb24gZml0cyB0byBub24temVybyBwb3J0aW9uIG9mIGdlbmVzLiBXZSBmaXJzdCB0YWtlIHRoZSBub24temVybyBwb3J0aW9uIG9mIHRoZSBnZW5lcy4KCiMjIyBGb2xkIGNoYW5nZSBpbiBtZWFuIGluIG5vbi16ZXJvIHBvcnRpb24gey50YWJzZXR9CgpgYGB7ciwgZWNobz1GQUxTRX0KIyB0YWtlIHRoZSBub24temVybyBwb3J0aW9uIGluIGVhY2ggZ2VuZQpiYXRjaF9zZXAgPC0gZ3JvdXBfc2VwIDwtIG5vbnplcm9fY3RzIDwtIHN0dWRpZXNfc2VwIDwtIGxpc3QoKQpmb3IoaSBpbiAxOm5yb3coY3RzKSl7CiAgbm9uemVyb19pbmQgPC0gd2hpY2goY3RzW2ksIF0hPTApCiAgYmF0Y2hfc2VwW1tpXV0gPC0gYXMuY2hhcmFjdGVyKGJhdGNoW25vbnplcm9faW5kXSkKICBncm91cF9zZXBbW2ldXSA8LSBhcy5jaGFyYWN0ZXIoZ3JvdXBbbm9uemVyb19pbmRdKQogIG5vbnplcm9fY3RzW1tpXV0gPC0gY3RzW2ksIG5vbnplcm9faW5kXQogIHN0dWRpZXNfc2VwW1tpXV0gPC0gYXMuY2hhcmFjdGVyKHJkc19vYmokRGF0YXNldFtub256ZXJvX2luZF0pCn0KIyBzYW5pdHkgY2hlY2sKaWYoIWlkZW50aWNhbChzYXBwbHkobm9uemVyb19jdHMsIGxlbmd0aCksIGFzLmludGVnZXIocm93U3VtcyhjdHMhPTApKSkpe3N0b3AoIkVycm9yIGluIHRha2luZyBub24temVybyBwb3J0aW9ucyEiKX0KCm5hbWVzKG5vbnplcm9fY3RzKSA8LSByb3duYW1lcyhjdHMpOyBuYW1lcyhiYXRjaF9zZXApIDwtIHJvd25hbWVzKGN0cyk7IG5hbWVzKGdyb3VwX3NlcCkgPC0gcm93bmFtZXMoY3RzKQpgYGAKCiMjIyMgIENoYW5nZSBXUlQgY29uZGl0aW9uIGluIEc2CgpXaXRoaW4gKipHNioqLCB3ZSBjb21wYXJlIG1lYW4gKGhlcmUgcmVmZXJzIHRvIG5vbi16ZXJvIG1lYW4pIGFjcm9zcyBiaW9sb2dpY2FsIGNvbmRpdGlvbiBncm91cHMuIFNwZWNpZmljYWxseSwgKip3ZSBzYXZlZCB0aGUgcHJldmlvdXMgREUgYW5hbHlzaXMgcmVzdWx0cyB1c2luZyBlZGdlUiwgb24gY291bnRzIGNvbnRhaW5pbmcgemVyb3MqKi4gV2UgY2FsbCBhbGwgZ2VuZXMgd2l0aCAkXGxvZyhGQykgPj0gMCQgYXMgInVwIiBnZW5lcywgYW5kICRcbG9nKEZDKSA8IDAkIGFzICJkb3duIiBnZW5lcy4gVGhlIHRvcCA1MCAidXAiIGFuZCAiZG93biIgZ2VuZXMgYXJlIHN0aWxsIGRldGVybWluZWQgYnkgdGhlIHByZXZpb3VzIERFIGNvbnRhaW5pbmcgemVyb3MuIAoKYGBge3IsIGVjaG89RkFMU0V9CiMgdGFrZSBHNgpncm91cF9zZXBfYmF0Y2gxIDwtIG5vbnplcm9fY3RzX2JhdGNoMSA8LSBsaXN0KCkKZm9yKGkgaW4gMTpsZW5ndGgobm9uemVyb19jdHMpKXsKICBncm91cF9zZXBfYmF0Y2gxW1tpXV0gPC0gZ3JvdXBfc2VwW1tpXV1bYmF0Y2hfc2VwW1tpXV09PSJHNiJdCiAgbm9uemVyb19jdHNfYmF0Y2gxW1tpXV0gPC0gbm9uemVyb19jdHNbW2ldXVtiYXRjaF9zZXBbW2ldXT09Ikc2Il0KfQpuYW1lcyhub256ZXJvX2N0c19iYXRjaDEpIDwtIG5hbWVzKGdyb3VwX3NlcF9iYXRjaDEpIDwtIHJvd25hbWVzKGN0cykKCiMgc3BsaXQgaW50byBjb250cm9scyAmIGNhc2VzCm5vbnplcm9fY3RzX2IxX2N0cmxzIDwtIG5vbnplcm9fY3RzX2IxX2Nhc2VzIDwtIGxpc3QoKQpmb3IoaiBpbiAxOmxlbmd0aChub256ZXJvX2N0c19iYXRjaDEpKXsKICBub256ZXJvX2N0c19iMV9jdHJsc1tbal1dIDwtIG5vbnplcm9fY3RzX2JhdGNoMVtbal1dW2dyb3VwX3NlcF9iYXRjaDFbW2pdXT09Ik5vbi1wcm9ncmVzc29yIl0KICBub256ZXJvX2N0c19iMV9jYXNlc1tbal1dIDwtIG5vbnplcm9fY3RzX2JhdGNoMVtbal1dW2dyb3VwX3NlcF9iYXRjaDFbW2pdXT09IlByb2dyZXNzb3IiXQp9I2lkZW50aWNhbChzYXBwbHkobm9uemVyb19jdHNfYjFfY3RybHMsIGxlbmd0aCkgKyBzYXBwbHkobm9uemVyb19jdHNfYjFfY2FzZXMsIGxlbmd0aCksIHNhcHBseShub256ZXJvX2N0c19iYXRjaDEsbGVuZ3RoKSkKbmFtZXMobm9uemVyb19jdHNfYjFfY3RybHMpIDwtIG5hbWVzKG5vbnplcm9fY3RzX2IxX2Nhc2VzKSA8LSByb3duYW1lcyhjdHMpCgojIHRvcCA1MCB1cCBhbmQgZG93biBpbmRpY2VzCnRvcF91cF9pbmQgPC0gaGVhZChjb25kX3VwX2luZHMsIDUwKQp0b3BfZG93bl9pbmQgPC0gaGVhZChjb25kX2Rvd25faW5kcywgNTApCmxlYXN0X2RlX2luZCA8LSBjKHRhaWwoY29uZF91cF9pbmRzLCA1MCksIHRhaWwoY29uZF9kb3duX2luZHMsIDUwKSkKCiMgY2FsY3VsYXRlIG1lYW4gaW4gdG9wIHVwLCBkb3duIGFuZCBsZWFzdCBERQpjYXQoIiMjIyMjIyAgQ2hhbmdlcyBpbiBNRUFOIG5vbi16ZXJvIGdlbmUgY291bnRzICAjIyMjIyNcbiIpCm1lYW5fbm9uemVyb2N0c19tYXQgPC0gbWF0cml4KE5BLCBucm93PTIsIG5jb2w9MywgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGRpbW5hbWVzPWxpc3QoYygiTm9uLXByb2dyZXNzb3IiLCAiUHJvZ3Jlc3NvciIpLCBjKCJ0b3A1MCB1cCIsICJ0b3A1MCBkb3duIiwgIjEwMCBsZWFzdCBERSIpKSkKbWVhbl9ub256ZXJvY3RzX21hdFsiTm9uLXByb2dyZXNzb3IiLCAidG9wNTAgdXAiXSA8LSBtZWFuKGRvLmNhbGwoYywgbm9uemVyb19jdHNfYjFfY3RybHNbdG9wX3VwX2luZF0pKQptZWFuX25vbnplcm9jdHNfbWF0WyJQcm9ncmVzc29yIiwgInRvcDUwIHVwIl0gPC0gbWVhbihkby5jYWxsKGMsIG5vbnplcm9fY3RzX2IxX2Nhc2VzW3RvcF91cF9pbmRdKSkKbWVhbl9ub256ZXJvY3RzX21hdFsiTm9uLXByb2dyZXNzb3IiLCAidG9wNTAgZG93biJdIDwtIG1lYW4oZG8uY2FsbChjLCBub256ZXJvX2N0c19iMV9jdHJsc1t0b3BfZG93bl9pbmRdKSkKbWVhbl9ub256ZXJvY3RzX21hdFsiUHJvZ3Jlc3NvciIsICJ0b3A1MCBkb3duIl0gPC0gbWVhbihkby5jYWxsKGMsIG5vbnplcm9fY3RzX2IxX2Nhc2VzW3RvcF9kb3duX2luZF0pKQptZWFuX25vbnplcm9jdHNfbWF0WyJOb24tcHJvZ3Jlc3NvciIsICIxMDAgbGVhc3QgREUiXSA8LSBtZWFuKGRvLmNhbGwoYywgbm9uemVyb19jdHNfYjFfY3RybHNbbGVhc3RfZGVfaW5kXSkpCm1lYW5fbm9uemVyb2N0c19tYXRbIlByb2dyZXNzb3IiLCAiMTAwIGxlYXN0IERFIl0gPC0gbWVhbihkby5jYWxsKGMsIG5vbnplcm9fY3RzX2IxX2Nhc2VzW2xlYXN0X2RlX2luZF0pKQpwcmludChyb3VuZChtZWFuX25vbnplcm9jdHNfbWF0LDEpKQpgYGAKCmBgYHtyLGVjaG89RkFMU0V9CmNhdCgiIyMjIyMjICBDaGFuZ2VzIGluIE1FRElBTiBub24temVybyBnZW5lIGNvdW50cyAgIyMjIyMjXG4iKQptZWRpYW5fbm9uemVyb2N0c19tYXQgPC0gbWF0cml4KE5BLCBucm93PTIsIG5jb2w9MywgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGRpbW5hbWVzPWxpc3QoYygiTm9uLXByb2dyZXNzb3IiLCAiUHJvZ3Jlc3NvciIpLCBjKCJ0b3A1MCB1cCIsICJ0b3A1MCBkb3duIiwgIjEwMCBsZWFzdCBERSIpKSkKbWVkaWFuX25vbnplcm9jdHNfbWF0WyJOb24tcHJvZ3Jlc3NvciIsICJ0b3A1MCB1cCJdIDwtIG1lZGlhbihkby5jYWxsKGMsIG5vbnplcm9fY3RzX2IxX2N0cmxzW3RvcF91cF9pbmRdKSkKbWVkaWFuX25vbnplcm9jdHNfbWF0WyJQcm9ncmVzc29yIiwgInRvcDUwIHVwIl0gPC0gbWVkaWFuKGRvLmNhbGwoYywgbm9uemVyb19jdHNfYjFfY2FzZXNbdG9wX3VwX2luZF0pKQptZWRpYW5fbm9uemVyb2N0c19tYXRbIk5vbi1wcm9ncmVzc29yIiwgInRvcDUwIGRvd24iXSA8LSBtZWRpYW4oZG8uY2FsbChjLCBub256ZXJvX2N0c19iMV9jdHJsc1t0b3BfZG93bl9pbmRdKSkKbWVkaWFuX25vbnplcm9jdHNfbWF0WyJQcm9ncmVzc29yIiwgInRvcDUwIGRvd24iXSA8LSBtZWRpYW4oZG8uY2FsbChjLCBub256ZXJvX2N0c19iMV9jYXNlc1t0b3BfZG93bl9pbmRdKSkKbWVkaWFuX25vbnplcm9jdHNfbWF0WyJOb24tcHJvZ3Jlc3NvciIsICIxMDAgbGVhc3QgREUiXSA8LSBtZWRpYW4oZG8uY2FsbChjLCBub256ZXJvX2N0c19iMV9jdHJsc1tsZWFzdF9kZV9pbmRdKSkKbWVkaWFuX25vbnplcm9jdHNfbWF0WyJQcm9ncmVzc29yIiwgIjEwMCBsZWFzdCBERSJdIDwtIG1lZGlhbihkby5jYWxsKGMsIG5vbnplcm9fY3RzX2IxX2Nhc2VzW2xlYXN0X2RlX2luZF0pKQpwcmludChyb3VuZChtZWRpYW5fbm9uemVyb2N0c19tYXQsMSkpCmBgYAoKKipDb25jbHVzaW9uczogKiogCgorIEJpb2xvZ2ljYWwgZm9sZCBjaGFuZ2UgKGluIG5vbi16ZXJvIHBvcnRpb24pIGNvbXBhcmluZyBhdmVyYWdlIGNvdW50cyAqKmluIHRvcCBnZW5lcyoqIGlzIGFib3V0IDEuMi0xLjggKG1lYW4pLgorIE8gY291bnRzIGRpZCBub3Qgc3Ryb25nbHkgYWZmZWN0IGJpb2xvZ2ljYWwgc2lnbmFsIGluIHRlcm1zIG9mIGF2ZXJhZ2UgY291bnRzICoqaW4gdG9wIGdlbmVzKiogLgoKCiMjIyMgIENoYW5nZSBXUlQgYmF0Y2ggaW4gbm9uLXByb2dyZXNzb3JzCgpTaW1pbGFybHksIHdlIGNvbXBhcmUgbm9uLXplcm8gbWVhbiAqKmluIHRvcCBnZW5lcyoqIGFjcm9zcyBiYXRjaGVzIHdpdGhpbiAiTm9uLXByb2dyZXNzb3JzIiBvZiBBZnJpY2EgYW5kIEc2IHN0dWRpZXMuIEhlcmUg4oCcdG9wIGdlbmVz4oCdIHJlZmVyIHRvIHRvcCBnZW5lIGxpc3RzIGZyb20gcHJldmlvdXMgREUgd2l0aGluIGNvbnRyb2wgc2FtcGxlcyBjb21wYXJpbmcgYmF0Y2hlcy4KCmBgYHtyLCBlY2hvPUZBTFNFfQojIHRha2UgY29udHJvbHMKYmF0Y2hfc2VwX2NvbmQwIDwtIG5vbnplcm9fY3RzX2NvbmQwIDwtIGxpc3QoKQpmb3IoaSBpbiAxOmxlbmd0aChub256ZXJvX2N0cykpewogIGJhdGNoX3NlcF9jb25kMFtbaV1dIDwtIGJhdGNoX3NlcFtbaV1dW2dyb3VwX3NlcFtbaV1dPT0iTm9uLXByb2dyZXNzb3IiXQogIG5vbnplcm9fY3RzX2NvbmQwW1tpXV0gPC0gbm9uemVyb19jdHNbW2ldXVtncm91cF9zZXBbW2ldXT09Ik5vbi1wcm9ncmVzc29yIl0KfQpuYW1lcyhiYXRjaF9zZXBfY29uZDApIDwtIG5hbWVzKG5vbnplcm9fY3RzX2NvbmQwKSA8LSByb3duYW1lcyhjdHMpCgojIHNwbGl0IGludG8gYmF0Y2ggMSAmIDIKbm9uemVyb19jdHNfY29uZDBfYmF0Y2gxIDwtIG5vbnplcm9fY3RzX2NvbmQwX2JhdGNoMiA8LSBsaXN0KCkKZm9yKGogaW4gMTpsZW5ndGgobm9uemVyb19jdHMpKXsKICBub256ZXJvX2N0c19jb25kMF9iYXRjaDFbW2pdXSA8LSBub256ZXJvX2N0c19jb25kMFtbal1dW2JhdGNoX3NlcF9jb25kMFtbal1dPT0iQWZyaWNhIl0KICBub256ZXJvX2N0c19jb25kMF9iYXRjaDJbW2pdXSA8LSBub256ZXJvX2N0c19jb25kMFtbal1dW2JhdGNoX3NlcF9jb25kMFtbal1dPT0iRzYiXQp9Cm5hbWVzKG5vbnplcm9fY3RzX2NvbmQwX2JhdGNoMSkgPC0gbmFtZXMobm9uemVyb19jdHNfY29uZDBfYmF0Y2gyKSA8LSByb3duYW1lcyhjdHMpCgojIHRvcCA1MCB1cCBhbmQgZG93biBpbmRpY2VzCnRvcF91cF9pbmQgPC0gaGVhZChiYXRjaF91cF9pbmRzLCA1MCkKdG9wX2Rvd25faW5kIDwtIGhlYWQoYmF0Y2hfZG93bl9pbmRzLCA1MCkKbGVhc3RfZGVfaW5kIDwtIGModGFpbChiYXRjaF91cF9pbmRzLCA1MCksIHRhaWwoYmF0Y2hfZG93bl9pbmRzLCA1MCkpCgojIGNhbGN1bGF0ZSBtZWFuIGluIHRvcCB1cCwgZG93biBhbmQgbGVhc3QgREUKY2F0KCIjIyMjIyMgIENoYW5nZXMgaW4gTUVBTiBub24temVybyBnZW5lIGNvdW50cyAgIyMjIyMjXG4iKQptZWFuX25vbnplcm9jdHNfbWF0IDwtIG1hdHJpeChOQSwgbnJvdz0yLCBuY29sPTMsIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICBkaW1uYW1lcz1saXN0KGMoIkFmcmljYSIsICJHNiIpLCBjKCJ0b3A1MCB1cCIsICJ0b3A1MCBkb3duIiwgIjEwMCBsZWFzdCBERSIpKSkKbWVhbl9ub256ZXJvY3RzX21hdFsiQWZyaWNhIiwgInRvcDUwIHVwIl0gPC0gbWVhbihkby5jYWxsKGMsIG5vbnplcm9fY3RzX2NvbmQwX2JhdGNoMVt0b3BfdXBfaW5kXSkpCm1lYW5fbm9uemVyb2N0c19tYXRbIkc2IiwgInRvcDUwIHVwIl0gPC0gbWVhbihkby5jYWxsKGMsIG5vbnplcm9fY3RzX2NvbmQwX2JhdGNoMlt0b3BfdXBfaW5kXSkpCm1lYW5fbm9uemVyb2N0c19tYXRbIkFmcmljYSIsICJ0b3A1MCBkb3duIl0gPC0gbWVhbihkby5jYWxsKGMsIG5vbnplcm9fY3RzX2NvbmQwX2JhdGNoMVt0b3BfZG93bl9pbmRdKSkKbWVhbl9ub256ZXJvY3RzX21hdFsiRzYiLCAidG9wNTAgZG93biJdIDwtIG1lYW4oZG8uY2FsbChjLCBub256ZXJvX2N0c19jb25kMF9iYXRjaDJbdG9wX2Rvd25faW5kXSkpCm1lYW5fbm9uemVyb2N0c19tYXRbIkFmcmljYSIsICIxMDAgbGVhc3QgREUiXSA8LSBtZWFuKGRvLmNhbGwoYywgbm9uemVyb19jdHNfY29uZDBfYmF0Y2gxW2xlYXN0X2RlX2luZF0pKQptZWFuX25vbnplcm9jdHNfbWF0WyJHNiIsICIxMDAgbGVhc3QgREUiXSA8LSBtZWFuKGRvLmNhbGwoYywgbm9uemVyb19jdHNfY29uZDBfYmF0Y2gyW2xlYXN0X2RlX2luZF0pKQpwcmludChyb3VuZChtZWFuX25vbnplcm9jdHNfbWF0LDEpKQpgYGAKCmBgYHtyLCBlY2hvPUZBTFNFfQojIGNhbGN1bGF0ZSBtZWRpYW4gaW4gdG9wIHVwLCBkb3duIGFuZCBsZWFzdCBERQpjYXQoIiMjIyMjIyAgQ2hhbmdlcyBpbiBNRURJQU4gbm9uLXplcm8gZ2VuZSBjb3VudHMgICMjIyMjI1xuIikKbWVkaWFuX25vbnplcm9jdHNfbWF0IDwtIG1hdHJpeChOQSwgbnJvdz0yLCBuY29sPTMsIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGRpbW5hbWVzPWxpc3QoYygiQWZyaWNhIiwgIkc2IiksIGMoInRvcDUwIHVwIiwgInRvcDUwIGRvd24iLCAiMTAwIGxlYXN0IERFIikpKQptZWRpYW5fbm9uemVyb2N0c19tYXRbIkFmcmljYSIsICJ0b3A1MCB1cCJdIDwtIG1lZGlhbihkby5jYWxsKGMsIG5vbnplcm9fY3RzX2NvbmQwX2JhdGNoMVt0b3BfdXBfaW5kXSkpCm1lZGlhbl9ub256ZXJvY3RzX21hdFsiRzYiLCAidG9wNTAgdXAiXSA8LSBtZWRpYW4oZG8uY2FsbChjLCBub256ZXJvX2N0c19jb25kMF9iYXRjaDJbdG9wX3VwX2luZF0pKQptZWRpYW5fbm9uemVyb2N0c19tYXRbIkFmcmljYSIsICJ0b3A1MCBkb3duIl0gPC0gbWVkaWFuKGRvLmNhbGwoYywgbm9uemVyb19jdHNfY29uZDBfYmF0Y2gxW3RvcF9kb3duX2luZF0pKQptZWRpYW5fbm9uemVyb2N0c19tYXRbIkc2IiwgInRvcDUwIGRvd24iXSA8LSBtZWRpYW4oZG8uY2FsbChjLCBub256ZXJvX2N0c19jb25kMF9iYXRjaDJbdG9wX2Rvd25faW5kXSkpCm1lZGlhbl9ub256ZXJvY3RzX21hdFsiQWZyaWNhIiwgIjEwMCBsZWFzdCBERSJdIDwtIG1lZGlhbihkby5jYWxsKGMsIG5vbnplcm9fY3RzX2NvbmQwX2JhdGNoMVtsZWFzdF9kZV9pbmRdKSkKbWVkaWFuX25vbnplcm9jdHNfbWF0WyJHNiIsICIxMDAgbGVhc3QgREUiXSA8LSBtZWRpYW4oZG8uY2FsbChjLCBub256ZXJvX2N0c19jb25kMF9iYXRjaDJbbGVhc3RfZGVfaW5kXSkpCnByaW50KHJvdW5kKG1lZGlhbl9ub256ZXJvY3RzX21hdCwxKSkKYGBgCgoqKkNvbmNsdXNpb25zOioqIAoKKyBNZWFuIGJhdGNoIGVmZmVjdCBmb2xkIGNoYW5nZSAobm9uLXplcm8gcG9ydGlvbikgY29tcGFyaW5nIGF2ZXJhZ2UgY291bnRzICoqaW4gdG9wIGdlbmVzKiogcmFuZ2VzIGZyb20gMS4xNi0zLjMgKG1lYW4pLiAKKyBPIGNvdW50cyBkaWQgbm90IHN0cm9uZ2x5IGFmZmVjdCBtZWFuIGJhdGNoIGVmZmVjdCBpbiB0ZXJtcyBvZiBhdmVyYWdlIGNvdW50cyAqKmluIHRvcCBnZW5lcyoqLgoKCiMjIyBCYXRjaCBtZWFuIHdpdGggMCBjb3VudHMgcmVtb3ZlZCAKCioqTWVkaWFuIChvZiBhbGwgZ2VuZXMpKiogZ2VuZS13aXNlIG1lYW4gYWZ0ZXIgcmVtb3ZpbmcgemVyb3M6IAoKYGBge3IsIGVjaG89RkFMU0V9Cm1lYW5fdGJfcm16ZXJvIDwtIG1hdHJpeChOQSwgbnJvdz0yLCBuY29sPTMsIAogICAgICAgICAgICAgICAgICAgICAgICBkaW1uYW1lcz1saXN0KGMoIk5vbi1wcm9ncmVzc29yIiwgIlByb2dyZXNzb3IiKSwgYygiQWZyaWNhIiwgIkc2IiwgIkJyYXppbDEiKSkpCmN0c19ybXplcm8gPC0gY3RzOyBjdHNfcm16ZXJvW2N0c19ybXplcm89PTBdIDwtIE5BCm1lYW5fdGJfcm16ZXJvWyJOb24tcHJvZ3Jlc3NvciIsICJBZnJpY2EiXSA8LSBtZWRpYW4ocm93TWVhbnMoY3RzX3JtemVyb1ssIGJhdGNoPT0iQWZyaWNhIiZncm91cD09Ik5vbi1wcm9ncmVzc29yIl0sIG5hLnJtPVRSVUUpLCBuYS5ybT1UUlVFKQptZWFuX3RiX3JtemVyb1siUHJvZ3Jlc3NvciIsICJBZnJpY2EiXSA8LSBtZWRpYW4ocm93TWVhbnMoY3RzX3JtemVyb1ssIGJhdGNoPT0iQWZyaWNhIiZncm91cD09IlByb2dyZXNzb3IiXSwgbmEucm09VFJVRSksIG5hLnJtPVRSVUUpCm1lYW5fdGJfcm16ZXJvWyJOb24tcHJvZ3Jlc3NvciIsICJHNiJdIDwtIG1lZGlhbihyb3dNZWFucyhjdHNfcm16ZXJvWywgYmF0Y2g9PSJHNiImZ3JvdXA9PSJOb24tcHJvZ3Jlc3NvciJdLCBuYS5ybT1UUlVFKSwgbmEucm09VFJVRSkKbWVhbl90Yl9ybXplcm9bIlByb2dyZXNzb3IiLCAiRzYiXSA8LSBtZWRpYW4ocm93TWVhbnMoY3RzX3JtemVyb1ssIGJhdGNoPT0iRzYiJmdyb3VwPT0iUHJvZ3Jlc3NvciJdLCBuYS5ybT1UUlVFKSwgbmEucm09VFJVRSkKbWVhbl90Yl9ybXplcm9bIk5vbi1wcm9ncmVzc29yIiwgIkJyYXppbDEiXSA8LSBtZWRpYW4ocm93TWVhbnMoY3RzX3JtemVyb1ssIGJhdGNoPT0iQnJhemlsXzEiJmdyb3VwPT0iTm9uLXByb2dyZXNzb3IiXSwgbmEucm09VFJVRSksIG5hLnJtPVRSVUUpCm1lYW5fdGJfcm16ZXJvWyJQcm9ncmVzc29yIiwgIkJyYXppbDEiXSA8LSBtZWRpYW4ocm93TWVhbnMoY3RzX3JtemVyb1ssIGJhdGNoPT0iQnJhemlsXzEiJmdyb3VwPT0iUHJvZ3Jlc3NvciJdLCBuYS5ybT1UUlVFKSwgbmEucm09VFJVRSkKcHJpbnQocm91bmQobWVhbl90Yl9ybXplcm8sIDIpKQpgYGAKClNjYWxlZCBieSB0aGF0IG9mIEFmcmljYToKCmBgYHtyLCBlY2hvPUZBTFNFfQptZWFuX3RiX3JtemVyb19zY2FsZWQgPC0gYXBwbHkobWVhbl90Yl9ybXplcm8sIDIsIGZ1bmN0aW9uKHgpe3gvbWVhbl90Yl9ybXplcm9bLCJBZnJpY2EiXX0pCnByaW50KHJvdW5kKG1lYW5fdGJfcm16ZXJvX3NjYWxlZCwgMikpCmBgYAoKCiMjIyBCYXRjaCBkaXNwZXJzaW9uIHdpdGggMCBjb3VudHMgcmVtb3ZlZCAKCkRpc3BlcnNpb24gZXN0aW1hdGVzIGFyZSBtb3JlIGxpa2VseSBpbXBhY3RlZCBieSAwIGNvdW50cy4gV2UgcmUtZXN0aW1hdGUgdGhlIGRpc3BlcnNpb25zIGluIGVhY2ggYmF0Y2gsIHVzaW5nIG5vbi16ZXJvIHBvcnRpb24gb2YgZWFjaCBnZW5lLiBUaGVuIHdlIGNvbXBhcmUgdGhlIGRpc3BlcnNpb24gZXN0aW1hdGVzIGFjcm9zcyBiYXRjaGVzLgoKYGBge3IsIGVjaG89RkFMU0V9CmxvYWQoZmlsZS5wYXRoKG91dHB1dF9kaXIsICJkaXNwc19ub256ZXJvLlJEYXRhIikpCmRpc3Bfbm9uemVyb19sc3QgPC0gbGlzdChBZnJpY2E9ZGlzcF9ub256ZXJvX2FmcmljYSwgRzY9ZGlzcF9ub256ZXJvX0c2LAogICAgICAgICAgICAgICAgICAgICAgICAgSW5kaWE9ZGlzcF9ub256ZXJvX2luZGlhLCBCcmF6aWxfMT1kaXNwX25vbnplcm9fYnpsMSwgCiAgICAgICAgICAgICAgICAgICAgICAgICBCcmF6aWxfMj1kaXNwX25vbnplcm9fYnpsMikKY2F0KCIjIyMjICBTdGF0aXN0aWNzIGFib3V0IGRpc3BlcnNpb24gZXN0aW1hdGVzIChmcm9tIE5PTi1aRVJPIHBvcnRpb25zKSBmcm9tIHRoZSB0d28gYmF0Y2hlcyAgIyMjI1xuIikKZGlzcF9zdGF0cyA8LSBsYXBwbHkoYyhtaW4sIG1lZGlhbiwgbWVhbiwgbWF4KSwgZnVuY3Rpb24oZmYpe3NhcHBseShkaXNwX25vbnplcm9fbHN0LCBmZil9KQpkaXNwX3N0YXRzIDwtIGRvLmNhbGwocmJpbmQsIGRpc3Bfc3RhdHMpCnJvd25hbWVzKGRpc3Bfc3RhdHMpIDwtIGMoIm1pbiBkaXNwLiIsICJtZWRpYW4gZGlzcC4iLCAibWVhbiBkaXNwLiIsICJtYXggZGlzcC4iKQpwcmludChyb3VuZChkaXNwX3N0YXRzLCA0KSkKYGBgCgpgYGB7ciwgZWNobz1GQUxTRSwgbWVzc2FnZT1GQUxTRX0KZGlzcF9ub256ZXJvX2RmIDwtIGRhdGEuZnJhbWUoQmF0Y2g9YyhyZXAoIkFmcmljYSIsIGxlbmd0aChkaXNwX25vbnplcm9fYWZyaWNhKSksIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJlcCgiRzYiLCBsZW5ndGgoZGlzcF9ub256ZXJvX0c2KSksCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcmVwKCJJbmRpYSIsIGxlbmd0aChkaXNwX25vbnplcm9faW5kaWEpKSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICByZXAoIkJyYXppbF8xIiwgbGVuZ3RoKGRpc3Bfbm9uemVyb19iemwxKSksCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcmVwKCJCcmF6aWxfMiIsIGxlbmd0aChkaXNwX25vbnplcm9fYnpsMikpKSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdmFsdWU9ZG8uY2FsbChjLCBkaXNwX25vbnplcm9fbHN0KSkKZ2dwbG90KGRpc3Bfbm9uemVyb19kZiAsIGFlcyh4PUJhdGNoLCB5PXZhbHVlKSkgKwogIGdlb21fdmlvbGluKCkgKwogIGxhYnMoeD0iQmF0Y2giLCB5PSJFc3RpbWF0ZWQgZ2VuZS13aXNlIGRpc3BlcnNpb24gb24gTk9OLVpFUk8gY291bnRzIiwgCiAgICAgICB0aXRsZT0iQ29tcGFyaXNvbiBvZiBlc3RpbWF0ZWQgZGlzcGVyc2lvbiBhY3Jvc3MgYmF0Y2hlcyIpICsKICBzdGF0X3N1bW1hcnkoZnVuLnk9bWVhbiwgY29sb3VyPSJkYXJrcmVkIiwgZ2VvbT0icG9pbnQiLCBzaGFwZT0xOCwgc2l6ZT0zKSAjKwogICNzY2FsZV95X2NvbnRpbnVvdXMobGltaXRzPWMoMCwgMSkpCmBgYAoKKipDb25jbHVzaW9uczoqKgoKKyBNZWFuIGRpc3BlcnNpb24gb2YgQnJhemlsIGJhdGNoIDEgaXMgcm91Z2hseSAzLjQgdGltZXMgdGhhdCBvZiBJbmRpYS4KKyBUaGUgYWJzb2x1dGUgdmFsdWUgb2YgbWF4IGdlbmUtd2lzZSBkaXNwZXJzaW9uIGFyZSByZWR1Y2VkIGFmdGVyIDAgY291bnRzIGFyZSByZW1vdmVkLgorIEluIHRoaXMgcmVwb3J0LCBkaXNwZXJzaW9uIGFyZSBjYWxjdWxhdGVkIGJ5IGRpZmZlcmVudCBtZXRob2RzIGJlZm9yZSBhbmQgYWZ0ZXIgcmVtb3ZpbmcgMCBjb3VudHMuICoqTm90IGRpcmVjdGx5IGNvbXBhcmFibGUuKioKKyBXZSBzaG93IGluIGFub3RoZXIgYW5hbHlzaXMgKCpUQl9ydW5fbm9uemVyb19kaXNwcy5SKikgdGhhdCAqKnRoZSBkaWZmZXJlbmNlIGluIGRpc3BlcnNpb24gaXMgcmVkdWNlZCBhZnRlciByZW1vdmluZyAwcyoqLgoKCiMjIyBCYXRjaCB2YXJpYW5jZSB3aXRoIDAgY291bnRzIHJlbW92ZWQgCgoqKk1lZGlhbioqIGdlbmUtd2lzZSB2YXJpYW5jZSBhZnRlciByZW1vdmluZyB6ZXJvczogCgpgYGB7ciwgZWNobz1GQUxTRX0KdmFyX3RiX3JtemVybyA8LSBtYXRyaXgoTkEsIG5yb3c9MiwgbmNvbD0zLCAKICAgICAgICAgICAgICAgICAgICAgICAgZGltbmFtZXM9bGlzdChjKCJOb24tcHJvZ3Jlc3NvciIsICJQcm9ncmVzc29yIiksIGMoIkFmcmljYSIsICJHNiIsICJCcmF6aWwxIikpKQpjdHNfcm16ZXJvIDwtIGN0czsgY3RzX3JtemVyb1tjdHNfcm16ZXJvPT0wXSA8LSBOQQp2YXJfdGJfcm16ZXJvWyJOb24tcHJvZ3Jlc3NvciIsICJBZnJpY2EiXSA8LSBtZWRpYW4ocm93VmFycyhjdHNfcm16ZXJvWywgYmF0Y2g9PSJBZnJpY2EiJmdyb3VwPT0iTm9uLXByb2dyZXNzb3IiXSwgbmEucm09VFJVRSksIG5hLnJtPVRSVUUpCnZhcl90Yl9ybXplcm9bIlByb2dyZXNzb3IiLCAiQWZyaWNhIl0gPC0gbWVkaWFuKHJvd1ZhcnMoY3RzX3JtemVyb1ssIGJhdGNoPT0iQWZyaWNhIiZncm91cD09IlByb2dyZXNzb3IiXSwgbmEucm09VFJVRSksIG5hLnJtPVRSVUUpCnZhcl90Yl9ybXplcm9bIk5vbi1wcm9ncmVzc29yIiwgIkc2Il0gPC0gbWVkaWFuKHJvd1ZhcnMoY3RzX3JtemVyb1ssIGJhdGNoPT0iRzYiJmdyb3VwPT0iTm9uLXByb2dyZXNzb3IiXSwgbmEucm09VFJVRSksIG5hLnJtPVRSVUUpCnZhcl90Yl9ybXplcm9bIlByb2dyZXNzb3IiLCAiRzYiXSA8LSBtZWRpYW4ocm93VmFycyhjdHNfcm16ZXJvWywgYmF0Y2g9PSJHNiImZ3JvdXA9PSJQcm9ncmVzc29yIl0sIG5hLnJtPVRSVUUpLCBuYS5ybT1UUlVFKQp2YXJfdGJfcm16ZXJvWyJOb24tcHJvZ3Jlc3NvciIsICJCcmF6aWwxIl0gPC0gbWVkaWFuKHJvd1ZhcnMoY3RzX3JtemVyb1ssIGJhdGNoPT0iQnJhemlsXzEiJmdyb3VwPT0iTm9uLXByb2dyZXNzb3IiXSwgbmEucm09VFJVRSksIG5hLnJtPVRSVUUpCnZhcl90Yl9ybXplcm9bIlByb2dyZXNzb3IiLCAiQnJhemlsMSJdIDwtIG1lZGlhbihyb3dWYXJzKGN0c19ybXplcm9bLCBiYXRjaD09IkJyYXppbF8xIiZncm91cD09IlByb2dyZXNzb3IiXSwgbmEucm09VFJVRSksIG5hLnJtPVRSVUUpCnByaW50KHJvdW5kKHZhcl90Yl9ybXplcm8sIDIpKQpgYGAKClNjYWxlZCBieSB0aGF0IG9mIEFmcmljYToKCmBgYHtyLCBlY2hvPUZBTFNFfQp2YXJfdGJfcm16ZXJvX3NjYWxlZCA8LSBhcHBseSh2YXJfdGJfcm16ZXJvLCAyLCBmdW5jdGlvbih4KXt4L3Zhcl90Yl9ybXplcm9bLCJBZnJpY2EiXX0pCnByaW50KHJvdW5kKHZhcl90Yl9ybXplcm9fc2NhbGVkLCAyKSkKYGBgCgoKIyMjIElzIHRoZXJlIGEgZGlmZmVyZW5jZSBpbiB6ZXJvIHBvcnRpb25zIGFjcm9zcyBiYXRjaGVzPwoKQW5vdGhlciBxdWVzdGlvbiByZWxhdGVkIHRvIGJhdGNoIGVmZmVjdCwgaXMgd2hldGhlciB0aGVyZSBpcyBhbnkgZGlmZmVyZW5jZSBpbiB0aGUgcGVyY2VudGFnZSBvZiAwIGNvdW50cyBpbiBhIGdlbmUgYmV0d2VlbiB0d28gYmF0Y2hlcy4gCgpgYGB7ciwgZWNobz1GQUxTRSwgbWVzc2FnZT1GQUxTRX0Kbl96ZXJvc19iYXRjaF9hZnJpY2EgPC0gYXBwbHkoY3RzWywgYmF0Y2g9PSJBZnJpY2EiXSwgMSwgZnVuY3Rpb24oeCl7bGVuZ3RoKHdoaWNoKHg9PTApKX0pCnBlcmNlbnRfemVyb3NfYmF0Y2hfYWZyaWNhIDwtIG5femVyb3NfYmF0Y2hfYWZyaWNhIC8gc3VtKGJhdGNoPT0iQWZyaWNhIikKbl96ZXJvc19iYXRjaF9HNiA8LSBhcHBseShjdHNbLCBiYXRjaD09Ikc2Il0sIDEsIGZ1bmN0aW9uKHgpe2xlbmd0aCh3aGljaCh4PT0wKSl9KQpwZXJjZW50X3plcm9zX2JhdGNoX0c2IDwtIG5femVyb3NfYmF0Y2hfRzYgLyBzdW0oYmF0Y2g9PSJHNiIpCm5femVyb3NfYmF0Y2hfaW5kaWEgPC0gYXBwbHkoY3RzWywgYmF0Y2g9PSJJbmRpYSJdLCAxLCBmdW5jdGlvbih4KXtsZW5ndGgod2hpY2goeD09MCkpfSkKcGVyY2VudF96ZXJvc19iYXRjaF9pbmRpYSA8LSBuX3plcm9zX2JhdGNoX2luZGlhIC8gc3VtKGJhdGNoPT0iSW5kaWEiKQpuX3plcm9zX2JhdGNoX2J6bDEgPC0gYXBwbHkoY3RzWywgYmF0Y2g9PSJCcmF6aWxfMSJdLCAxLCBmdW5jdGlvbih4KXtsZW5ndGgod2hpY2goeD09MCkpfSkKcGVyY2VudF96ZXJvc19iYXRjaF9iemwxIDwtIG5femVyb3NfYmF0Y2hfYnpsMSAvIHN1bShiYXRjaD09IkJyYXppbF8xIikKbl96ZXJvc19iYXRjaF9iemwyIDwtIGFwcGx5KGN0c1ssIGJhdGNoPT0iQnJhemlsXzIiXSwgMSwgZnVuY3Rpb24oeCl7bGVuZ3RoKHdoaWNoKHg9PTApKX0pCnBlcmNlbnRfemVyb3NfYmF0Y2hfYnpsMiA8LSBuX3plcm9zX2JhdGNoX2J6bDIgLyBzdW0oYmF0Y2g9PSJCcmF6aWxfMiIpCgpwZXJjZW50X3plcm9zX2JhdGNoX2RmIDwtIGRhdGEuZnJhbWUoQWZyaWNhPXBlcmNlbnRfemVyb3NfYmF0Y2hfYWZyaWNhLCBHNj1wZXJjZW50X3plcm9zX2JhdGNoX0c2LAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgSW5kaWE9cGVyY2VudF96ZXJvc19iYXRjaF9pbmRpYSwgQnJhemlsXzE9cGVyY2VudF96ZXJvc19iYXRjaF9iemwxLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgQnJhemlsXzI9cGVyY2VudF96ZXJvc19iYXRjaF9iemwyKQpwZXJjZW50X3plcm9zX2JhdGNoX2RmX21sdCA8LSBtZWx0KHBlcmNlbnRfemVyb3NfYmF0Y2hfZGYsIHZhcmlhYmxlLm5hbWU9IkJhdGNoIikKZ2dwbG90KHBlcmNlbnRfemVyb3NfYmF0Y2hfZGZfbWx0LCBhZXMoeD1CYXRjaCwgeT12YWx1ZSkpICsKICBnZW9tX3Zpb2xpbigpICsKICBsYWJzKHk9IlBlcmNlbnRhZ2Ugb2YgMCBjb3VudHMgaW4gYSBzaW5nbGUgZ2VuZSIpICsKICB0aGVtZShheGlzLnRpdGxlLng9ZWxlbWVudF9ibGFuaygpKQpgYGAKCioqQ29uY2x1c2lvbnM6KioKCisgVGhlcmUgaXNuJ3QgYW4gb2J2aW91cyBkaWZmZXJlbmNlIGluIHplcm8gZnJhY3Rpb25zIGJldHdlZW4gYmF0Y2hlcyAoYXNpZGUgZnJvbSBCcmF6aWwgYmF0Y2ggMiB3aGljaCBpcyB0b28gc21hbGwpLgoKCiMjIyBHb29kbmVzcyBvZiBmaXQgZm9yIE5CIGRpc3RyaWJ1dGlvbiB0byBub24temVybyBwb3J0aW9uIG9mIGdlbmVzCgpJdCBpcyBkaWZmaWN1bHQgdG8gZXZhbHVhdGUgcXVhbnRpdGF0aXZlbHkgdGhlIGdvb2RuZXNzLW9mLWZpdCBvZiBOQiBkaXN0cmlidXRpb24gb24gZGF0YS4gSW5zdGVhZCwgd2UgZ2VuZXJhdGUgUS1RIHBsb3RzIGZvciAxMDAgcmFuZG9tbHkgc2VsZWN0ZWQgZ2VuZXMsIGNvbXBhcmluZyBkYXRhIHdpdGggTkIgZGlzdHJpYnV0aW9uIHVzaW5nIE1MIGVzdGltYXRlZCBwYXJhbWV0ZXJzLiBXZSBnZW5lcmF0ZSB0aGVzZSBwbG90cyAqKndpdGhpbiBHNi9BZnJpY2EsIGZvciBjYXNlcyBhbmQgY29udHJvbCBzYW1wbGVzIHNlcGFyYXRlbHkqKi4gRmlndXJlcyBhcmUgc3RvcmVkIHVuZGVyIHtvdXRwdXRfZGlyfS9xcXBsb3RzX3tTdHVkeX0vLgoKYGBge3IsIGVjaG89RkFMU0UsIHJlc3VsdHM9ImhpZGUifQppZighZGlyLmV4aXN0cyhmaWxlLnBhdGgob3V0cHV0X2RpciwgInFxcGxvdHNfRzYiKSkpe2Rpci5jcmVhdGUoZmlsZS5wYXRoKG91dHB1dF9kaXIsICJxcXBsb3RzX0c2IikpfQpzZXQuc2VlZCgxMjM0KQpOX3NlbF9uYiA8LSAxMDAKY2hvc2VuX2lkX25iIDwtIHNhbXBsZSgxOm5yb3cocmRzX29iaiksIE5fc2VsX25iLCByZXBsYWNlPUZBTFNFKQpjdHNfc3Vic2V0X25iIDwtIGN0c1tjaG9zZW5faWRfbmIsIF0KZm9yKGkgaW4gMTpOX3NlbF9uYil7CiAgIyBjYXNlIHNhbXBsZXMKICBjdXJyX2N0cyA8LSBjdHNfc3Vic2V0X25iW2ksIGJhdGNoPT0iRzYiICYgZ3JvdXA9PSJQcm9ncmVzc29yIl0KICBjdXJyX2N0cyA8LSBjdXJyX2N0c1tjdXJyX2N0cyE9MF0KICBpZihsZW5ndGgodW5pcXVlKGN1cnJfY3RzKSkgPD0gMyB8IHZhcihjdXJyX2N0cyk9PTApe25leHR9CiAgZGYgPC0gZGF0YS5mcmFtZSh5PWN1cnJfY3RzKQogIHBhcmFtcyA8LSBmaXRkaXN0cihkZiR5LCAibmVnYXRpdmUgYmlub21pYWwiKSRlc3RpbWF0ZQogIAogIHBuZyhwYXN0ZTAob3V0cHV0X2RpciwgIi9xcXBsb3RzX0c2L2dlbmUiLCBpLCAiX2Nhc2VzLnBuZyIpLCAKICAgICAgd2lkdGg9NSwgaGVpZ2h0PTUsIHVuaXRzPSJpbiIsIHJlcz0zMDApCiAgcHJpbnQoZ2dwbG90KGRmLCBhZXMoc2FtcGxlPXkpKSArCiAgICAgICAgICBzdGF0X3FxKGRpc3RyaWJ1dGlvbj1xbmJpbm9tLCBkcGFyYW1zPXBhcmFtcykgKyAKICAgICAgICAgIHN0YXRfcXFfbGluZShkaXN0cmlidXRpb249cW5iaW5vbSwgZHBhcmFtcz1wYXJhbXMpICsKICAgICAgICAgIGxhYnModGl0bGU9IlEtUSBwbG90OiBHNiBQcm9ncmVzc29ycyIpKQogIGRldi5vZmYoKQogIHJtKGN1cnJfY3RzLCBkZiwgcGFyYW1zKQogIAogICMgY29udHJvbCBzYW1wbGVzCiAgY3Vycl9jdHMgPC0gY3RzX3N1YnNldF9uYltpLCBiYXRjaD09Ikc2IiAmIGdyb3VwPT0iTm9uLXByb2dyZXNzb3IiXQogIGN1cnJfY3RzIDwtIGN1cnJfY3RzW2N1cnJfY3RzIT0wXQogIGlmKGxlbmd0aCh1bmlxdWUoY3Vycl9jdHMpKSA8PSAzIHwgdmFyKGN1cnJfY3RzKT09MCl7bmV4dH0KICBkZiA8LSBkYXRhLmZyYW1lKHk9Y3Vycl9jdHMpCiAgcGFyYW1zIDwtIGZpdGRpc3RyKGRmJHksICJuZWdhdGl2ZSBiaW5vbWlhbCIpJGVzdGltYXRlCiAgCiAgcG5nKHBhc3RlMChvdXRwdXRfZGlyLCAiL3FxcGxvdHNfRzYvZ2VuZSIsIGksICJfY29udHJvbHMucG5nIiksIAogICAgICB3aWR0aD01LCBoZWlnaHQ9NSwgdW5pdHM9ImluIiwgcmVzPTMwMCkKICBwcmludChnZ3Bsb3QoZGYsIGFlcyhzYW1wbGU9eSkpICsKICAgICAgICAgIHN0YXRfcXEoZGlzdHJpYnV0aW9uPXFuYmlub20sIGRwYXJhbXM9cGFyYW1zKSArIAogICAgICAgICAgc3RhdF9xcV9saW5lKGRpc3RyaWJ1dGlvbj1xbmJpbm9tLCBkcGFyYW1zPXBhcmFtcykgKwogICAgICAgICAgbGFicyh0aXRsZT0iUS1RIHBsb3Q6IEc2IE5vbi1wcm9ncmVzc29ycyIpKQogIGRldi5vZmYoKQp9CmBgYAoKYGBge3IsIGVjaG89RkFMU0UsIHJlc3VsdHM9ImhpZGUifQppZighZGlyLmV4aXN0cyhmaWxlLnBhdGgob3V0cHV0X2RpciwgInFxcGxvdHNfYWZyaWNhIikpKXtkaXIuY3JlYXRlKGZpbGUucGF0aChvdXRwdXRfZGlyLCAicXFwbG90c19hZnJpY2EiKSl9CnNldC5zZWVkKDEyMzQpCk5fc2VsX25iIDwtIDEwMApjaG9zZW5faWRfbmIgPC0gc2FtcGxlKDE6bnJvdyhyZHNfb2JqKSwgTl9zZWxfbmIsIHJlcGxhY2U9RkFMU0UpCmN0c19zdWJzZXRfbmIgPC0gY3RzW2Nob3Nlbl9pZF9uYiwgXQpmb3IoaSBpbiAxOk5fc2VsX25iKXsKICAjIGNhc2Ugc2FtcGxlcwogIGN1cnJfY3RzIDwtIGN0c19zdWJzZXRfbmJbaSwgYmF0Y2g9PSJBZnJpY2EiICYgZ3JvdXA9PSJQcm9ncmVzc29yIl0KICBjdXJyX2N0cyA8LSBjdXJyX2N0c1tjdXJyX2N0cyE9MF0KICBpZihsZW5ndGgodW5pcXVlKGN1cnJfY3RzKSkgPD0gMyB8IHZhcihjdXJyX2N0cyk9PTApe25leHR9CiAgZGYgPC0gZGF0YS5mcmFtZSh5PWN1cnJfY3RzKQogIHBhcmFtcyA8LSBmaXRkaXN0cihkZiR5LCAibmVnYXRpdmUgYmlub21pYWwiKSRlc3RpbWF0ZQogIAogIHBuZyhwYXN0ZTAob3V0cHV0X2RpciwgIi9xcXBsb3RzX2FmcmljYS9nZW5lIiwgaSwgIl9jYXNlcy5wbmciKSwgCiAgICAgIHdpZHRoPTUsIGhlaWdodD01LCB1bml0cz0iaW4iLCByZXM9MzAwKQogIHByaW50KGdncGxvdChkZiwgYWVzKHNhbXBsZT15KSkgKwogICAgICAgICAgc3RhdF9xcShkaXN0cmlidXRpb249cW5iaW5vbSwgZHBhcmFtcz1wYXJhbXMpICsgCiAgICAgICAgICBzdGF0X3FxX2xpbmUoZGlzdHJpYnV0aW9uPXFuYmlub20sIGRwYXJhbXM9cGFyYW1zKSArCiAgICAgICAgICBsYWJzKHRpdGxlPSJRLVEgcGxvdDogQWZyaWNhIFByb2dyZXNzb3JzIikpCiAgZGV2Lm9mZigpCiAgcm0oY3Vycl9jdHMsIGRmLCBwYXJhbXMpCiAgCiAgIyBjb250cm9sIHNhbXBsZXMKICBjdXJyX2N0cyA8LSBjdHNfc3Vic2V0X25iW2ksIGJhdGNoPT0iQWZyaWNhIiAmIGdyb3VwPT0iTm9uLXByb2dyZXNzb3IiXQogIGN1cnJfY3RzIDwtIGN1cnJfY3RzW2N1cnJfY3RzIT0wXQogIGlmKGxlbmd0aCh1bmlxdWUoY3Vycl9jdHMpKSA8PSAzIHwgdmFyKGN1cnJfY3RzKT09MCl7bmV4dH0KICBkZiA8LSBkYXRhLmZyYW1lKHk9Y3Vycl9jdHMpCiAgcGFyYW1zIDwtIGZpdGRpc3RyKGRmJHksICJuZWdhdGl2ZSBiaW5vbWlhbCIpJGVzdGltYXRlCiAgCiAgcG5nKHBhc3RlMChvdXRwdXRfZGlyLCAiL3FxcGxvdHNfYWZyaWNhL2dlbmUiLCBpLCAiX2NvbnRyb2xzLnBuZyIpLCAKICAgICAgd2lkdGg9NSwgaGVpZ2h0PTUsIHVuaXRzPSJpbiIsIHJlcz0zMDApCiAgcHJpbnQoZ2dwbG90KGRmLCBhZXMoc2FtcGxlPXkpKSArCiAgICAgICAgICBzdGF0X3FxKGRpc3RyaWJ1dGlvbj1xbmJpbm9tLCBkcGFyYW1zPXBhcmFtcykgKyAKICAgICAgICAgIHN0YXRfcXFfbGluZShkaXN0cmlidXRpb249cW5iaW5vbSwgZHBhcmFtcz1wYXJhbXMpICsKICAgICAgICAgIGxhYnModGl0bGU9IlEtUSBwbG90OiBBZnJpY2EgTm9uLXByb2dyZXNzb3JzIikpCiAgZGV2Lm9mZigpCn0KYGBgCgoKIyMgTW9yZSBqdXN0aWZpY2F0aW9uIGZvciBoYXZpbmcgZGlmZmVyZW50IGRpc3BlcnNpb24gcGFyYW1ldGVyIGZvciBkaWZmZXJlbnQgYmF0Y2hlcyAKCkZpbmFsbHksIGEgdmVyeSBpbXBvcnRhbnQgYXNzdW1wdGlvbiBvZiBDb21CYXQtc2VxIG1vZGVsIChjb21wYXJlZCB0byBhZGRpbmcgYmF0Y2ggY292YXJpYXRlcyBpbiBsaW5lYXIgbW9kZWwgb2YgZWRnZVIgYW5kIERFU2VxKSwgaXMgdGhhdCAqKmhhdmluZyBhIGRpZmZlcmVudCBkaXNwZXJzaW9uIHBhcmFtZXRlciBmb3IgZWFjaCBiYXRjaCBpcyBiZW5lZmljaWFsIGZvciBERSBwZXJmb3JtYW5jZS4gQXMgYXJndWVkIGJ5IG1hbnksIGlmIG5vdCBhbGwsIG9mIHRoZXNlIHBhcGVycywgYWNjdXJhdGUgZXN0aW1hdGlvbiBvZiBkaXNwZXJzaW9uIHBhcmFtdGVycyBhcmUgaW1wb3J0YW50IGZvciBERSBkZXRlY3Rpb24qKi4gQXMgd2UgaGF2ZSBzZWVuIGFib3ZlLCB0aGVyZSBpcyBzb21lIGRpZmZlcmVuY2UgaW4gZGlzcGVyc2lvbiBkaXN0cmlidXRpb24gYWNyb3NzIGJhdGNoZXMuIElmIGRpc3BlcnNpb24gZXN0aW1hdGVzIHdpdGhpbiBlYWNoIGJhdGNoIGFuZCB1c2luZyB0aGUgd2hvbGUgc3R1ZHkgYXJlIG5vdCBjb25zaXN0ZW50IHdpdGggZWFjaCBvdGhlciwgdGhlbiBpdCBpcyBqdXN0aWZpY2F0aW9uIHRoYXQgd2UgbWF5IG5lZWQgZGlmZmVyZW50IGRpcHNlcnNpb24gcGFyYW1ldGVyIGZvciBkaWZmZXJlbnQgYmF0Y2hlcywgYW5kIGl0IGNvdWxkIGJlIGdvb2QgZm9yIERFLgoKSGVyZSB3ZSBnZW5lcmF0ZSBzY2F0dGVyIHBsb3RzIGNvbXBhcmluZyBkaXNwZXJzaW9uIGVzdGltYXRlcyB3aXRoaW4gZWFjaCBiYXRjaCB0byBlc3RpbWF0ZXMgZnJvbSB3aG9sZSBkYXRhc2V0ICgqKmluY2x1ZGluZyBiYXRjaCBhcyBhIGNvdmFyaWF0ZSBpbiB3aG9sZSBzdHVkeSoqKS4KCiMjIyBJbiBCcmF6aWwgey50YWJzZXR9CgpgYGB7ciwgZWNobz1GQUxTRSwgcmVzdWx0cz0naGlkZSd9CmN0c19icmF6aWwgPC0gY3RzWywgcmRzX29iaiREYXRhc2V0PT0iQnJhemlsIl0KZ3JvdXBfYnJhemlsIDwtIGdyb3VwW3Jkc19vYmokRGF0YXNldD09IkJyYXppbCJdCmJhdGNoX2JyYXppbCA8LSBhcy5mYWN0b3IoYXMuY2hhcmFjdGVyKGJhdGNoW3Jkc19vYmokRGF0YXNldD09IkJyYXppbCJdKSkKCiMjICBEaXNwZXJzaW9uIGluIGJhdGNoZXMgJiBpbiB3aG9sZSBzdHVkeSAoaW5jbHVkaW5nIGJhdGNoIGFzIGNvdmFyaWF0ZSkgKGVkZ2VSKQp5X2JhdGNoMSA8LSBER0VMaXN0KGNvdW50cz1jdHNfYnJhemlsWywgYmF0Y2hfYnJhemlsPT0iQnJhemlsXzEiXSwgCiAgICAgICAgICAgICAgICAgICAgZ3JvdXA9YXMuZmFjdG9yKGFzLmNoYXJhY3Rlcihncm91cF9icmF6aWxbYmF0Y2hfYnJhemlsPT0iQnJhemlsXzEiXSkpKQp5X2JhdGNoMSA8LSBjYWxjTm9ybUZhY3RvcnMoeV9iYXRjaDEsIG1ldGhvZD0iVE1NIikKZGVzaWduX2JhdGNoMSA8LSBtb2RlbC5tYXRyaXgofmFzLmZhY3Rvcihhcy5jaGFyYWN0ZXIoZ3JvdXBfYnJhemlsW2JhdGNoX2JyYXppbD09IkJyYXppbF8xIl0pKSkKeV9iYXRjaDEgPC0gZXN0aW1hdGVEaXNwKHlfYmF0Y2gxLCBkZXNpZ25fYmF0Y2gxKQoKeV9iYXRjaDIgPC0gREdFTGlzdChjb3VudHM9Y3RzX2JyYXppbFssIGJhdGNoX2JyYXppbD09IkJyYXppbF8yIl0pCnlfYmF0Y2gyIDwtIGNhbGNOb3JtRmFjdG9ycyh5X2JhdGNoMiwgbWV0aG9kPSJUTU0iKQpkZXNpZ25fYmF0Y2gyIDwtIE5VTEwKeV9iYXRjaDIgPC0gZXN0aW1hdGVEaXNwKHlfYmF0Y2gyLCBkZXNpZ25fYmF0Y2gyKQoKeV93aG9sZSA8LSBER0VMaXN0KGNvdW50cz1jdHNfYnJhemlsKQp5X3dob2xlIDwtIGNhbGNOb3JtRmFjdG9ycyh5X3dob2xlLCBtZXRob2Q9IlRNTSIpCmRlc2lnbl93aG9sZSA8LSBtb2RlbC5tYXRyaXgofiBncm91cF9icmF6aWwgKyBiYXRjaF9icmF6aWwpCnlfd2hvbGUgPC0gZXN0aW1hdGVEaXNwKHlfd2hvbGUsIGRlc2lnbl93aG9sZSkKCmRpc3AxX2dlbmVfZWRnZVIgPC0geV9iYXRjaDEkdGFnd2lzZS5kaXNwZXJzaW9uCmRpc3AyX2dlbmVfZWRnZVIgPC0geV9iYXRjaDIkdGFnd2lzZS5kaXNwZXJzaW9uCmRpc3BXX2dlbmVfZWRnZVIgPC0geV93aG9sZSR0YWd3aXNlLmRpc3BlcnNpb24KCmRpc3AxX3RyZW5kX2VkZ2VSIDwtIHlfYmF0Y2gxJHRyZW5kZWQuZGlzcGVyc2lvbgpkaXNwMl90cmVuZF9lZGdlUiA8LSB5X2JhdGNoMiR0cmVuZGVkLmRpc3BlcnNpb24KZGlzcFdfdHJlbmRfZWRnZVIgPC0geV93aG9sZSR0cmVuZGVkLmRpc3BlcnNpb24KCgojIyAgRGlzcGVyc2lvbiBpbiBiYXRjaGVzICYgaW4gd2hvbGUgc3R1ZHkgKGluY2x1ZGluZyBiYXRjaCBhcyBjb3ZhcmlhdGUpIChERVNlcTIpCmRkczEgPC0gREVTZXFEYXRhU2V0RnJvbU1hdHJpeChjb3VudERhdGE9Y3RzX2JyYXppbFssIGJhdGNoX2JyYXppbD09IkJyYXppbF8xIl0sIGRlc2lnbj1+R3JvdXAsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb2xEYXRhPWRhdGEuZnJhbWUoR3JvdXA9YXMuZmFjdG9yKGFzLmNoYXJhY3Rlcihncm91cF9icmF6aWxbYmF0Y2hfYnJhemlsPT0iQnJhemlsXzEiXSkpKSkKZGRzMSA8LSBlc3RpbWF0ZVNpemVGYWN0b3JzKGRkczEpCmRkczEgPC0gZXN0aW1hdGVEaXNwZXJzaW9ucyhkZHMxKQoKZGRzMiA8LSBERVNlcURhdGFTZXRGcm9tTWF0cml4KGNvdW50RGF0YT1jdHNfYnJhemlsWywgYmF0Y2hfYnJhemlsPT0iQnJhemlsXzIiXSwgZGVzaWduPX4xLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY29sRGF0YT1kYXRhLmZyYW1lKEdyb3VwPWFzLmZhY3Rvcihhcy5jaGFyYWN0ZXIoZ3JvdXBfYnJhemlsW2JhdGNoX2JyYXppbD09IkJyYXppbF8yIl0pKSkpCmRkczIgPC0gZXN0aW1hdGVTaXplRmFjdG9ycyhkZHMyKQpkZHMyIDwtIGVzdGltYXRlRGlzcGVyc2lvbnMoZGRzMikKCmRkc1cgPC0gREVTZXFEYXRhU2V0RnJvbU1hdHJpeChjb3VudERhdGE9Y3RzX2JyYXppbCwgZGVzaWduPX4gR3JvdXAgKyBCYXRjaCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbERhdGE9ZGF0YS5mcmFtZShHcm91cD1ncm91cF9icmF6aWwsIEJhdGNoPWJhdGNoX2JyYXppbCkpCmRkc1cgPC0gZXN0aW1hdGVTaXplRmFjdG9ycyhkZHNXKQpkZHNXIDwtIGVzdGltYXRlRGlzcGVyc2lvbnMoZGRzVykKCmRpc3AxX2dlbmVfREVTZXEyIDwtIGRpc3BlcnNpb25zKGRkczEpCmRpc3AyX2dlbmVfREVTZXEyIDwtIGRpc3BlcnNpb25zKGRkczIpCmRpc3BXX2dlbmVfREVTZXEyIDwtIGRpc3BlcnNpb25zKGRkc1cpCmBgYAoKIyMjIyBHZW5lLXdpc2UgZGlzcGVyc2lvbiBlc3RpbWF0ZXMKCmBgYHtyLCBlY2hvPUZBTFNFLCByZXN1bHRzPSdoaWRlJywgZmlnLndpZHRoPTQsIGZpZy5oZWlnaHQ9Nn0KZGlzcHNfYWxsIDwtIGRhdGEuZnJhbWUoQmF0Y2gxLmVkZ2VSPWRpc3AxX2dlbmVfZWRnZVIsIAogICAgICAgICAgICAgICAgICAgICAgICBCYXRjaDIuZWRnZVI9ZGlzcDJfZ2VuZV9lZGdlUiwgCiAgICAgICAgICAgICAgICAgICAgICAgIFdob2xlLmVkZ2VSPWRpc3BXX2dlbmVfZWRnZVIsCiAgICAgICAgICAgICAgICAgICAgICAgIEJhdGNoMS5lZGdlUi50cmVuZD1kaXNwMV90cmVuZF9lZGdlUiwgCiAgICAgICAgICAgICAgICAgICAgICAgIEJhdGNoMi5lZGdlUi50cmVuZD1kaXNwMl90cmVuZF9lZGdlUiwgCiAgICAgICAgICAgICAgICAgICAgICAgIFdob2xlLmVkZ2VSLnRyZW5kPWRpc3BXX3RyZW5kX2VkZ2VSLAogICAgICAgICAgICAgICAgICAgICAgICBCYXRjaDEuREVTZXEyPWRpc3AxX2dlbmVfREVTZXEyLCAKICAgICAgICAgICAgICAgICAgICAgICAgQmF0Y2gyLkRFU2VxMj1kaXNwMl9nZW5lX0RFU2VxMiwgCiAgICAgICAgICAgICAgICAgICAgICAgIFdob2xlLkRFU2VxMj1kaXNwV19nZW5lX0RFU2VxMikKZGlzcHNfYWxsX2xvZzEwIDwtIGxvZzEwKGRpc3BzX2FsbCkKCnBsdF9yYW5nZV9lZGdlUiA8LSByYW5nZShjKGRpc3AxX2dlbmVfZWRnZVIsIGRpc3AyX2dlbmVfZWRnZVIsIGRpc3BXX2dlbmVfZWRnZVIpLCBuYS5ybT1UUlVFKQpwbHRfcmFuZ2VfZWRnZVJ0cmVuZCA8LSByYW5nZShjKGRpc3AxX3RyZW5kX2VkZ2VSLCBkaXNwMl90cmVuZF9lZGdlUiwgZGlzcFdfdHJlbmRfZWRnZVIpLCBuYS5ybT1UUlVFKQpwbHRfcmFuZ2VfREVTZXEyIDwtIHJhbmdlKGMoZGlzcDFfZ2VuZV9ERVNlcTIsIGRpc3AyX2dlbmVfREVTZXEyLCBkaXNwV19nZW5lX0RFU2VxMiksIG5hLnJtPVRSVUUpCgpwbHRfcmFuZ2VfZWRnZVJfbG9nMTAgPC0gbG9nMTAocGx0X3JhbmdlX2VkZ2VSKQpwbHRfcmFuZ2VfZWRnZVJ0cmVuZF9sb2cxMCA8LSBsb2cxMChwbHRfcmFuZ2VfZWRnZVJ0cmVuZCkKcGx0X3JhbmdlX0RFU2VxMl9sb2cxMCA8LSBsb2cxMChwbHRfcmFuZ2VfREVTZXEyKQoKZ2VuU2NhdHRlclBsb3QgPC0gZnVuY3Rpb24oZGYsIGFlcy54LCBhZXMueSwgbWV0aG9kLCBwbHQucmFuZ2UpewogIHAgPC0gZ2dwbG90KGRmLCBhZXMoeD1kZlssYWVzLnhdLCB5PWRmWyxhZXMueV0pKSArCiAgZ2VvbV9wb2ludCgpICsKICBnZW9tX2FibGluZShzbG9wZT0xLCBpbnRlcmNlcHQ9MCwgY29sb3I9ImJsdWUiLCBsaW5ldHlwZT0iZGFzaGVkIikgKwogIGxhYnModGl0bGU9c3ByaW50ZigiJXMsIFBlYXJzb24gY29yciA9ICVzIiwgbWV0aG9kLAogICAgICAgICAgICAgICAgICAgICByb3VuZChjb3IoZGZbLGFlcy54XSwgZGZbLGFlcy55XSwgdXNlPSJwYWlyd2lzZS5jb21wbGV0ZS5vYnMiLCBtZXRob2Q9InBlYXJzb24iKSwyKSkpICsKICBzY2FsZV94X2NvbnRpbnVvdXMobGltaXRzPXBsdC5yYW5nZSkgKwogIHNjYWxlX3lfY29udGludW91cyhsaW1pdHM9cGx0LnJhbmdlKQp9CgpwMVdfZWRnZVIgPC0gZ2VuU2NhdHRlclBsb3QoZGlzcHNfYWxsX2xvZzEwLCBhZXMueD0iV2hvbGUuZWRnZVIiLCBhZXMueT0iQmF0Y2gxLmVkZ2VSIiwgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICBtZXRob2Q9ImVkZ2VSIiwgcGx0LnJhbmdlPXBsdF9yYW5nZV9lZGdlUl9sb2cxMCkgKyAKICBsYWJzKHg9ImRpc3BlcnNpb24gKGxvZzEwIHNjYWxlKSAtIHdob2xlIGRhdGFzZXQiLCB5PSJkaXNwZXJzaW9uIChsb2cxMCBzY2FsZSkgLSBiYXRjaCAxIikKcDJXX2VkZ2VSIDwtIGdlblNjYXR0ZXJQbG90KGRpc3BzX2FsbF9sb2cxMCwgYWVzLng9Ildob2xlLmVkZ2VSIiwgYWVzLnk9IkJhdGNoMi5lZGdlUiIsIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgbWV0aG9kPSJlZGdlUiIsIHBsdC5yYW5nZT1wbHRfcmFuZ2VfZWRnZVJfbG9nMTApICsKICBsYWJzKHg9ImRpc3BlcnNpb24gKGxvZzEwIHNjYWxlKSAtIHdob2xlIGRhdGFzZXQiLCB5PSJkaXNwZXJzaW9uIChsb2cxMCBzY2FsZSkgLSBiYXRjaCAyIikKcDF2Ml9lZGdlUiA8LSBnZW5TY2F0dGVyUGxvdChkaXNwc19hbGxfbG9nMTAsIGFlcy54PSJCYXRjaDEuZWRnZVIiLCBhZXMueT0iQmF0Y2gyLmVkZ2VSIiwgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbWV0aG9kPSJlZGdlUiIsIHBsdC5yYW5nZT1wbHRfcmFuZ2VfZWRnZVJfbG9nMTApICsKICBsYWJzKHg9ImRpc3BlcnNpb24gKGxvZzEwIHNjYWxlKSAtIGJhdGNoIDEiLCB5PSJkaXNwZXJzaW9uIChsb2cxMCBzY2FsZSkgLSBiYXRjaCAyIikKIApwMVdfREVTZXEyIDwtIGdlblNjYXR0ZXJQbG90KGRpc3BzX2FsbF9sb2cxMCwgYWVzLng9Ildob2xlLkRFU2VxMiIsIGFlcy55PSJCYXRjaDEuREVTZXEyIiwgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbWV0aG9kPSJERVNlcTIiLCBwbHQucmFuZ2U9cGx0X3JhbmdlX0RFU2VxMl9sb2cxMCkgKyAKICBsYWJzKHg9ImRpc3BlcnNpb24gKGxvZzEwIHNjYWxlKSAtIHdob2xlIGRhdGFzZXQiLCB5PSJkaXNwZXJzaW9uIChsb2cxMCBzY2FsZSkgLSBiYXRjaCAxIikKcDJXX0RFU2VxMiA8LSBnZW5TY2F0dGVyUGxvdChkaXNwc19hbGxfbG9nMTAsIGFlcy54PSJXaG9sZS5ERVNlcTIiLCBhZXMueT0iQmF0Y2gyLkRFU2VxMiIsIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgIG1ldGhvZD0iREVTZXEyIiwgcGx0LnJhbmdlPXBsdF9yYW5nZV9ERVNlcTJfbG9nMTApICsKICBsYWJzKHg9ImRpc3BlcnNpb24gKGxvZzEwIHNjYWxlKSAtIHdob2xlIGRhdGFzZXQiLCB5PSJkaXNwZXJzaW9uIChsb2cxMCBzY2FsZSkgLSBiYXRjaCAyIikKcDF2Ml9ERVNlcTIgPC0gZ2VuU2NhdHRlclBsb3QoZGlzcHNfYWxsX2xvZzEwLCBhZXMueD0iQmF0Y2gxLkRFU2VxMiIsIGFlcy55PSJCYXRjaDIuREVTZXEyIiwgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG1ldGhvZD0iREVTZXEyIiwgcGx0LnJhbmdlPXBsdF9yYW5nZV9ERVNlcTJfbG9nMTApICsKICBsYWJzKHg9ImRpc3BlcnNpb24gKGxvZzEwIHNjYWxlKSAtIGJhdGNoIDEiLCB5PSJkaXNwZXJzaW9uIChsb2cxMCBzY2FsZSkgLSBiYXRjaCAyIikKCmdyaWQuYXJyYW5nZShwMVdfZWRnZVIsIHAxV19ERVNlcTIsIHAyV19lZGdlUiwgcDJXX0RFU2VxMiwgcDF2Ml9lZGdlUiwgcDF2Ml9ERVNlcTIsIG5yb3c9MywgbmNvbD0yKQpgYGAKCiMjIyMgVHJlbmRlZCBkaXNwZXJzaW9uIGVzdGltYXRlcwoKYGBge3IsIGVjaG89RkFMU0UsIHJlc3VsdHM9J2hpZGUnLCBmaWcud2lkdGg9NCwgZmlnLmhlaWdodD02fQpwMVdfZWRnZVIgPC0gZ2VuU2NhdHRlclBsb3QoZGlzcHNfYWxsX2xvZzEwLCBhZXMueD0iV2hvbGUuZWRnZVIudHJlbmQiLCBhZXMueT0iQmF0Y2gxLmVkZ2VSLnRyZW5kIiwgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICBtZXRob2Q9ImVkZ2VSIHRyZW5kIiwgcGx0LnJhbmdlPXBsdF9yYW5nZV9lZGdlUnRyZW5kX2xvZzEwKSArIAogIGxhYnMoeD0iZGlzcGVyc2lvbiAobG9nMTAgc2NhbGUpIC0gd2hvbGUgZGF0YXNldCIsIHk9ImRpc3BlcnNpb24gKGxvZzEwIHNjYWxlKSAtIGJhdGNoIDEiKQpwMldfZWRnZVIgPC0gZ2VuU2NhdHRlclBsb3QoZGlzcHNfYWxsX2xvZzEwLCBhZXMueD0iV2hvbGUuZWRnZVIudHJlbmQiLCBhZXMueT0iQmF0Y2gyLmVkZ2VSLnRyZW5kIiwgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICBtZXRob2Q9ImVkZ2VSIHRyZW5kIiwgcGx0LnJhbmdlPXBsdF9yYW5nZV9lZGdlUnRyZW5kX2xvZzEwKSArCiAgbGFicyh4PSJkaXNwZXJzaW9uIChsb2cxMCBzY2FsZSkgLSB3aG9sZSBkYXRhc2V0IiwgeT0iZGlzcGVyc2lvbiAobG9nMTAgc2NhbGUpIC0gYmF0Y2ggMiIpCnAxdjJfZWRnZVIgPC0gZ2VuU2NhdHRlclBsb3QoZGlzcHNfYWxsX2xvZzEwLCBhZXMueD0iQmF0Y2gxLmVkZ2VSLnRyZW5kIiwgYWVzLnk9IkJhdGNoMi5lZGdlUi50cmVuZCIsIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgIG1ldGhvZD0iZWRnZVIgdHJlbmQiLCBwbHQucmFuZ2U9cGx0X3JhbmdlX2VkZ2VSdHJlbmRfbG9nMTApICsKICBsYWJzKHg9ImRpc3BlcnNpb24gKGxvZzEwIHNjYWxlKSAtIGJhdGNoIDEiLCB5PSJkaXNwZXJzaW9uIChsb2cxMCBzY2FsZSkgLSBiYXRjaCAyIikKCmdyaWQuYXJyYW5nZShwMVdfZWRnZVIsIHAxV19ERVNlcTIsIHAyV19lZGdlUiwgcDJXX0RFU2VxMiwgcDF2Ml9lZGdlUiwgcDF2Ml9ERVNlcTIsIG5yb3c9MywgbmNvbD0yKQpgYGAKCgojIyMgQWZyaWNhIFZTIEc2IHsudGFic2V0fQoKYGBge3IsIGVjaG89RkFMU0UsIHJlc3VsdHM9J2hpZGUnfQpkaXNwc19hbGwgPC0gcmVhZFJEUyhmaWxlLnBhdGgob3V0cHV0X2RpciwgIlRCX2Rpc3BzX0FHLnJkcyIpKQpgYGAKCiMjIyMgR2VuZS13aXNlIGRpc3BlcnNpb24gZXN0aW1hdGVzCgpgYGB7ciwgZWNobz1GQUxTRSwgcmVzdWx0cz0naGlkZScsIGZpZy53aWR0aD00LCBmaWcuaGVpZ2h0PTZ9CmRpc3BzX2FsbF9sb2cxMCA8LSBsb2cxMChkaXNwc19hbGwpCgpwbHRfcmFuZ2VfZWRnZVIgPC0gcmFuZ2UoZGlzcHNfYWxsWywxOjNdLCBuYS5ybT1UUlVFKQpwbHRfcmFuZ2VfZWRnZVJ0cmVuZCA8LSByYW5nZShkaXNwc19hbGxbLDQ6Nl0sIG5hLnJtPVRSVUUpCnBsdF9yYW5nZV9ERVNlcTIgPC0gcmFuZ2UoZGlzcHNfYWxsWyw3OjldLCBuYS5ybT1UUlVFKQoKcGx0X3JhbmdlX2VkZ2VSX2xvZzEwIDwtIGxvZzEwKHBsdF9yYW5nZV9lZGdlUikKcGx0X3JhbmdlX2VkZ2VSdHJlbmRfbG9nMTAgPC0gbG9nMTAocGx0X3JhbmdlX2VkZ2VSdHJlbmQpCnBsdF9yYW5nZV9ERVNlcTJfbG9nMTAgPC0gbG9nMTAocGx0X3JhbmdlX0RFU2VxMikKCmdlblNjYXR0ZXJQbG90IDwtIGZ1bmN0aW9uKGRmLCBhZXMueCwgYWVzLnksIG1ldGhvZCwgcGx0LnJhbmdlKXsKICBwIDwtIGdncGxvdChkZiwgYWVzKHg9ZGZbLGFlcy54XSwgeT1kZlssYWVzLnldKSkgKwogIGdlb21fcG9pbnQoKSArCiAgZ2VvbV9hYmxpbmUoc2xvcGU9MSwgaW50ZXJjZXB0PTAsIGNvbG9yPSJibHVlIiwgbGluZXR5cGU9ImRhc2hlZCIpICsKICBsYWJzKHRpdGxlPXNwcmludGYoIiVzLCBQZWFyc29uIGNvcnIgPSAlcyIsIG1ldGhvZCwKICAgICAgICAgICAgICAgICAgICAgcm91bmQoY29yKGRmWyxhZXMueF0sIGRmWyxhZXMueV0sIHVzZT0icGFpcndpc2UuY29tcGxldGUub2JzIiwgbWV0aG9kPSJwZWFyc29uIiksMikpKSArCiAgc2NhbGVfeF9jb250aW51b3VzKGxpbWl0cz1wbHQucmFuZ2UpICsKICBzY2FsZV95X2NvbnRpbnVvdXMobGltaXRzPXBsdC5yYW5nZSkKfQoKcDFXX2VkZ2VSIDwtIGdlblNjYXR0ZXJQbG90KGRpc3BzX2FsbF9sb2cxMCwgYWVzLng9Ildob2xlLmVkZ2VSIiwgYWVzLnk9IkJhdGNoMS5lZGdlUiIsIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgbWV0aG9kPSJlZGdlUiIsIHBsdC5yYW5nZT1wbHRfcmFuZ2VfZWRnZVJfbG9nMTApICsgCiAgbGFicyh4PSJkaXNwZXJzaW9uIChsb2cxMCBzY2FsZSkgLSBBZnJpY2EgJiBHNiBtZXJnZWQiLCB5PSJkaXNwZXJzaW9uIChsb2cxMCBzY2FsZSkgLSBBZnJpY2EiKQpwMldfZWRnZVIgPC0gZ2VuU2NhdHRlclBsb3QoZGlzcHNfYWxsX2xvZzEwLCBhZXMueD0iV2hvbGUuZWRnZVIiLCBhZXMueT0iQmF0Y2gyLmVkZ2VSIiwgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICBtZXRob2Q9ImVkZ2VSIiwgcGx0LnJhbmdlPXBsdF9yYW5nZV9lZGdlUl9sb2cxMCkgKwogIGxhYnMoeD0iZGlzcGVyc2lvbiAobG9nMTAgc2NhbGUpIC0gQWZyaWNhICYgRzYgbWVyZ2VkIiwgeT0iZGlzcGVyc2lvbiAobG9nMTAgc2NhbGUpIC0gRzYiKQpwMXYyX2VkZ2VSIDwtIGdlblNjYXR0ZXJQbG90KGRpc3BzX2FsbF9sb2cxMCwgYWVzLng9IkJhdGNoMS5lZGdlUiIsIGFlcy55PSJCYXRjaDIuZWRnZVIiLCAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICBtZXRob2Q9ImVkZ2VSIiwgcGx0LnJhbmdlPXBsdF9yYW5nZV9lZGdlUl9sb2cxMCkgKwogIGxhYnMoeD0iZGlzcGVyc2lvbiAobG9nMTAgc2NhbGUpIC0gQWZyaWNhIiwgeT0iZGlzcGVyc2lvbiAobG9nMTAgc2NhbGUpIC0gRzYiKQogCnAxV19ERVNlcTIgPC0gZ2VuU2NhdHRlclBsb3QoZGlzcHNfYWxsX2xvZzEwLCBhZXMueD0iV2hvbGUuREVTZXEyIiwgYWVzLnk9IkJhdGNoMS5ERVNlcTIiLCAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICBtZXRob2Q9IkRFU2VxMiIsIHBsdC5yYW5nZT1wbHRfcmFuZ2VfREVTZXEyX2xvZzEwKSArIAogIGxhYnMoeD0iZGlzcGVyc2lvbiAobG9nMTAgc2NhbGUpIC0gQWZyaWNhICYgRzYgbWVyZ2VkIiwgeT0iZGlzcGVyc2lvbiAobG9nMTAgc2NhbGUpIC0gQWZyaWNhIikKcDJXX0RFU2VxMiA8LSBnZW5TY2F0dGVyUGxvdChkaXNwc19hbGxfbG9nMTAsIGFlcy54PSJXaG9sZS5ERVNlcTIiLCBhZXMueT0iQmF0Y2gyLkRFU2VxMiIsIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgIG1ldGhvZD0iREVTZXEyIiwgcGx0LnJhbmdlPXBsdF9yYW5nZV9ERVNlcTJfbG9nMTApICsKICBsYWJzKHg9ImRpc3BlcnNpb24gKGxvZzEwIHNjYWxlKSAtIEFmcmljYSAmIEc2IG1lcmdlZCIsIHk9ImRpc3BlcnNpb24gKGxvZzEwIHNjYWxlKSAtIEc2IikKcDF2Ml9ERVNlcTIgPC0gZ2VuU2NhdHRlclBsb3QoZGlzcHNfYWxsX2xvZzEwLCBhZXMueD0iQmF0Y2gxLkRFU2VxMiIsIGFlcy55PSJCYXRjaDIuREVTZXEyIiwgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG1ldGhvZD0iREVTZXEyIiwgcGx0LnJhbmdlPXBsdF9yYW5nZV9ERVNlcTJfbG9nMTApICsKICBsYWJzKHg9ImRpc3BlcnNpb24gKGxvZzEwIHNjYWxlKSAtIEFmcmljYSIsIHk9ImRpc3BlcnNpb24gKGxvZzEwIHNjYWxlKSAtIEc2IikKCmdyaWQuYXJyYW5nZShwMVdfZWRnZVIsIHAxV19ERVNlcTIsIHAyV19lZGdlUiwgcDJXX0RFU2VxMiwgcDF2Ml9lZGdlUiwgcDF2Ml9ERVNlcTIsIG5yb3c9MywgbmNvbD0yKQpgYGAKCiMjIyMgVHJlbmRlZCBkaXNwZXJzaW9uIGVzdGltYXRlcwoKYGBge3IsIGVjaG89RkFMU0UsIHJlc3VsdHM9J2hpZGUnLCBmaWcud2lkdGg9NCwgZmlnLmhlaWdodD02fQpwMVdfZWRnZVIgPC0gZ2VuU2NhdHRlclBsb3QoZGlzcHNfYWxsX2xvZzEwLCBhZXMueD0iV2hvbGUuZWRnZVIudHJlbmQiLCBhZXMueT0iQmF0Y2gxLmVkZ2VSLnRyZW5kIiwgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICBtZXRob2Q9ImVkZ2VSIHRyZW5kIiwgcGx0LnJhbmdlPXBsdF9yYW5nZV9lZGdlUnRyZW5kX2xvZzEwKSArIAogIGxhYnMoeD0iZGlzcGVyc2lvbiAobG9nMTAgc2NhbGUpIC0gQWZyaWNhICYgRzYgbWVyZ2VkIiwgeT0iZGlzcGVyc2lvbiAobG9nMTAgc2NhbGUpIC0gQWZyaWNhIikKcDJXX2VkZ2VSIDwtIGdlblNjYXR0ZXJQbG90KGRpc3BzX2FsbF9sb2cxMCwgYWVzLng9Ildob2xlLmVkZ2VSLnRyZW5kIiwgYWVzLnk9IkJhdGNoMi5lZGdlUi50cmVuZCIsIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgbWV0aG9kPSJlZGdlUiB0cmVuZCIsIHBsdC5yYW5nZT1wbHRfcmFuZ2VfZWRnZVJ0cmVuZF9sb2cxMCkgKwogIGxhYnMoeD0iZGlzcGVyc2lvbiAobG9nMTAgc2NhbGUpIC0gQWZyaWNhICYgRzYgbWVyZ2VkIiwgeT0iZGlzcGVyc2lvbiAobG9nMTAgc2NhbGUpIC0gRzYiKQpwMXYyX2VkZ2VSIDwtIGdlblNjYXR0ZXJQbG90KGRpc3BzX2FsbF9sb2cxMCwgYWVzLng9IkJhdGNoMS5lZGdlUi50cmVuZCIsIGFlcy55PSJCYXRjaDIuZWRnZVIudHJlbmQiLCAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICBtZXRob2Q9ImVkZ2VSIHRyZW5kIiwgcGx0LnJhbmdlPXBsdF9yYW5nZV9lZGdlUnRyZW5kX2xvZzEwKSArCiAgbGFicyh4PSJkaXNwZXJzaW9uIChsb2cxMCBzY2FsZSkgLSBBZnJpY2EiLCB5PSJkaXNwZXJzaW9uIChsb2cxMCBzY2FsZSkgLSBHNiIpCgpncmlkLmFycmFuZ2UocDFXX2VkZ2VSLCBwMVdfREVTZXEyLCBwMldfZWRnZVIsIHAyV19ERVNlcTIsIHAxdjJfZWRnZVIsIHAxdjJfREVTZXEyLCBucm93PTMsIG5jb2w9MikKYGBgCgojIyMgQnJhemlsIEJhdGNoIDEgVlMgSW5kaWEgey50YWJzZXR9CgpgYGB7ciwgZWNobz1GQUxTRSwgcmVzdWx0cz0naGlkZSd9CnJtKGRpc3BzX2FsbCwgZGlzcHNfYWxsX2xvZzEwKQpkaXNwc19hbGwgPC0gcmVhZFJEUyhmaWxlLnBhdGgob3V0cHV0X2RpciwgIlRCX2Rpc3BzX0JJLnJkcyIpKQpgYGAKCiMjIyMgR2VuZS13aXNlIGRpc3BlcnNpb24gZXN0aW1hdGVzCgpgYGB7ciwgZWNobz1GQUxTRSwgcmVzdWx0cz0naGlkZScsIGZpZy53aWR0aD00LCBmaWcuaGVpZ2h0PTZ9CmRpc3BzX2FsbF9sb2cxMCA8LSBsb2cxMChkaXNwc19hbGwpCgpwbHRfcmFuZ2VfZWRnZVIgPC0gcmFuZ2UoZGlzcHNfYWxsWywxOjNdLCBuYS5ybT1UUlVFKQpwbHRfcmFuZ2VfZWRnZVJ0cmVuZCA8LSByYW5nZShkaXNwc19hbGxbLDQ6Nl0sIG5hLnJtPVRSVUUpCnBsdF9yYW5nZV9ERVNlcTIgPC0gcmFuZ2UoZGlzcHNfYWxsWyw3OjldLCBuYS5ybT1UUlVFKQoKcGx0X3JhbmdlX2VkZ2VSX2xvZzEwIDwtIGxvZzEwKHBsdF9yYW5nZV9lZGdlUikKcGx0X3JhbmdlX2VkZ2VSdHJlbmRfbG9nMTAgPC0gbG9nMTAocGx0X3JhbmdlX2VkZ2VSdHJlbmQpCnBsdF9yYW5nZV9ERVNlcTJfbG9nMTAgPC0gbG9nMTAocGx0X3JhbmdlX0RFU2VxMikKCmdlblNjYXR0ZXJQbG90IDwtIGZ1bmN0aW9uKGRmLCBhZXMueCwgYWVzLnksIG1ldGhvZCwgcGx0LnJhbmdlKXsKICBwIDwtIGdncGxvdChkZiwgYWVzKHg9ZGZbLGFlcy54XSwgeT1kZlssYWVzLnldKSkgKwogIGdlb21fcG9pbnQoKSArCiAgZ2VvbV9hYmxpbmUoc2xvcGU9MSwgaW50ZXJjZXB0PTAsIGNvbG9yPSJibHVlIiwgbGluZXR5cGU9ImRhc2hlZCIpICsKICBsYWJzKHRpdGxlPXNwcmludGYoIiVzLCBQZWFyc29uIGNvcnIgPSAlcyIsIG1ldGhvZCwKICAgICAgICAgICAgICAgICAgICAgcm91bmQoY29yKGRmWyxhZXMueF0sIGRmWyxhZXMueV0sIHVzZT0icGFpcndpc2UuY29tcGxldGUub2JzIiwgbWV0aG9kPSJwZWFyc29uIiksMikpKSArCiAgc2NhbGVfeF9jb250aW51b3VzKGxpbWl0cz1wbHQucmFuZ2UpICsKICBzY2FsZV95X2NvbnRpbnVvdXMobGltaXRzPXBsdC5yYW5nZSkKfQoKcDFXX2VkZ2VSIDwtIGdlblNjYXR0ZXJQbG90KGRpc3BzX2FsbF9sb2cxMCwgYWVzLng9Ildob2xlLmVkZ2VSIiwgYWVzLnk9IkJhdGNoMS5lZGdlUiIsIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgbWV0aG9kPSJlZGdlUiIsIHBsdC5yYW5nZT1wbHRfcmFuZ2VfZWRnZVJfbG9nMTApICsgCiAgbGFicyh4PSJkaXNwZXJzaW9uIChsb2cxMCBzY2FsZSkgLSBCcmF6aWwgMSAmIEluZGlhIG1lcmdlZCIsIHk9ImRpc3BlcnNpb24gKGxvZzEwIHNjYWxlKSAtIEJyYXppbCAxIikKcDJXX2VkZ2VSIDwtIGdlblNjYXR0ZXJQbG90KGRpc3BzX2FsbF9sb2cxMCwgYWVzLng9Ildob2xlLmVkZ2VSIiwgYWVzLnk9IkJhdGNoMi5lZGdlUiIsIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgbWV0aG9kPSJlZGdlUiIsIHBsdC5yYW5nZT1wbHRfcmFuZ2VfZWRnZVJfbG9nMTApICsKICBsYWJzKHg9ImRpc3BlcnNpb24gKGxvZzEwIHNjYWxlKSAtIEJyYXppbCAxICYgSW5kaWEgbWVyZ2VkIiwgeT0iZGlzcGVyc2lvbiAobG9nMTAgc2NhbGUpIC0gSW5kaWEiKQpwMXYyX2VkZ2VSIDwtIGdlblNjYXR0ZXJQbG90KGRpc3BzX2FsbF9sb2cxMCwgYWVzLng9IkJhdGNoMS5lZGdlUiIsIGFlcy55PSJCYXRjaDIuZWRnZVIiLCAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICBtZXRob2Q9ImVkZ2VSIiwgcGx0LnJhbmdlPXBsdF9yYW5nZV9lZGdlUl9sb2cxMCkgKwogIGxhYnMoeD0iZGlzcGVyc2lvbiAobG9nMTAgc2NhbGUpIC0gQnJhemlsIDEiLCB5PSJkaXNwZXJzaW9uIChsb2cxMCBzY2FsZSkgLSBJbmRpYSIpCiAKcDFXX0RFU2VxMiA8LSBnZW5TY2F0dGVyUGxvdChkaXNwc19hbGxfbG9nMTAsIGFlcy54PSJXaG9sZS5ERVNlcTIiLCBhZXMueT0iQmF0Y2gxLkRFU2VxMiIsIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgIG1ldGhvZD0iREVTZXEyIiwgcGx0LnJhbmdlPXBsdF9yYW5nZV9ERVNlcTJfbG9nMTApICsgCiAgbGFicyh4PSJkaXNwZXJzaW9uIChsb2cxMCBzY2FsZSkgLSBCcmF6aWwgMSAmIEluZGlhIG1lcmdlZCIsIHk9ImRpc3BlcnNpb24gKGxvZzEwIHNjYWxlKSAtIEJyYXppbCAxIikKcDJXX0RFU2VxMiA8LSBnZW5TY2F0dGVyUGxvdChkaXNwc19hbGxfbG9nMTAsIGFlcy54PSJXaG9sZS5ERVNlcTIiLCBhZXMueT0iQmF0Y2gyLkRFU2VxMiIsIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgIG1ldGhvZD0iREVTZXEyIiwgcGx0LnJhbmdlPXBsdF9yYW5nZV9ERVNlcTJfbG9nMTApICsKICBsYWJzKHg9ImRpc3BlcnNpb24gKGxvZzEwIHNjYWxlKSAtIEJyYXppbCAxICYgSW5kaWEgbWVyZ2VkIiwgeT0iZGlzcGVyc2lvbiAobG9nMTAgc2NhbGUpIC0gSW5kaWEiKQpwMXYyX0RFU2VxMiA8LSBnZW5TY2F0dGVyUGxvdChkaXNwc19hbGxfbG9nMTAsIGFlcy54PSJCYXRjaDEuREVTZXEyIiwgYWVzLnk9IkJhdGNoMi5ERVNlcTIiLCAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbWV0aG9kPSJERVNlcTIiLCBwbHQucmFuZ2U9cGx0X3JhbmdlX0RFU2VxMl9sb2cxMCkgKwogIGxhYnMoeD0iZGlzcGVyc2lvbiAobG9nMTAgc2NhbGUpIC0gQnJhemlsIDEiLCB5PSJkaXNwZXJzaW9uIChsb2cxMCBzY2FsZSkgLSBJbmRpYSIpCgpncmlkLmFycmFuZ2UocDFXX2VkZ2VSLCBwMVdfREVTZXEyLCBwMldfZWRnZVIsIHAyV19ERVNlcTIsIHAxdjJfZWRnZVIsIHAxdjJfREVTZXEyLCBucm93PTMsIG5jb2w9MikKYGBgCgojIyMjIFRyZW5kZWQgZGlzcGVyc2lvbiBlc3RpbWF0ZXMKCmBgYHtyLCBlY2hvPUZBTFNFLCByZXN1bHRzPSdoaWRlJywgZmlnLndpZHRoPTQsIGZpZy5oZWlnaHQ9Nn0KcDFXX2VkZ2VSIDwtIGdlblNjYXR0ZXJQbG90KGRpc3BzX2FsbF9sb2cxMCwgYWVzLng9Ildob2xlLmVkZ2VSLnRyZW5kIiwgYWVzLnk9IkJhdGNoMS5lZGdlUi50cmVuZCIsIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgbWV0aG9kPSJlZGdlUiB0cmVuZCIsIHBsdC5yYW5nZT1wbHRfcmFuZ2VfZWRnZVJ0cmVuZF9sb2cxMCkgKyAKICBsYWJzKHg9ImRpc3BlcnNpb24gKGxvZzEwIHNjYWxlKSAtIEJyYXppbCAxICYgSW5kaWEgbWVyZ2VkIiwgeT0iZGlzcGVyc2lvbiAobG9nMTAgc2NhbGUpIC0gQnJhemlsIDEiKQpwMldfZWRnZVIgPC0gZ2VuU2NhdHRlclBsb3QoZGlzcHNfYWxsX2xvZzEwLCBhZXMueD0iV2hvbGUuZWRnZVIudHJlbmQiLCBhZXMueT0iQmF0Y2gyLmVkZ2VSLnRyZW5kIiwgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICBtZXRob2Q9ImVkZ2VSIHRyZW5kIiwgcGx0LnJhbmdlPXBsdF9yYW5nZV9lZGdlUnRyZW5kX2xvZzEwKSArCiAgbGFicyh4PSJkaXNwZXJzaW9uIChsb2cxMCBzY2FsZSkgLSBCcmF6aWwgMSAmIEluZGlhIG1lcmdlZCIsIHk9ImRpc3BlcnNpb24gKGxvZzEwIHNjYWxlKSAtIEluZGlhIikKcDF2Ml9lZGdlUiA8LSBnZW5TY2F0dGVyUGxvdChkaXNwc19hbGxfbG9nMTAsIGFlcy54PSJCYXRjaDEuZWRnZVIudHJlbmQiLCBhZXMueT0iQmF0Y2gyLmVkZ2VSLnRyZW5kIiwgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbWV0aG9kPSJlZGdlUiB0cmVuZCIsIHBsdC5yYW5nZT1wbHRfcmFuZ2VfZWRnZVJ0cmVuZF9sb2cxMCkgKwogIGxhYnMoeD0iZGlzcGVyc2lvbiAobG9nMTAgc2NhbGUpIC0gQnJhemlsIDEiLCB5PSJkaXNwZXJzaW9uIChsb2cxMCBzY2FsZSkgLSBJbmRpYSIpCgpncmlkLmFycmFuZ2UocDFXX2VkZ2VSLCBwMVdfREVTZXEyLCBwMldfZWRnZVIsIHAyV19ERVNlcTIsIHAxdjJfZWRnZVIsIHAxdjJfREVTZXEyLCBucm93PTMsIG5jb2w9MikKYGBgCgoKCiMjIFNlc3Npb24gaW5mbyAKCmBgYHtyLCBlY2hvPUZBTFNFfQpzZXNzaW9uSW5mbygpCmBgYAoKCgojIyBSZWZlcmVuY2VzCg==